react学习笔记(一)
这是我个人的一些react学习笔记,用于个人同步更新学习使用,如果对读者有帮助或者读者有什么需要交流的地方可以私信交流,之后的一些我个人学习react遇到的问题会更新到其他文章
一些小技巧:
对于平级的多个组件需要共享数据的解决方案
可以把组件的状态提升的共同的父组件上,然后把修改方法传入子组件(react中的数据流往往是单向数据流,不支持双向传递)
如果需要通过外部组件访问内部状态
可以创建一个新的状态并把修改方法传入子组件中,在子组件更新其内部状态的时候一起更新外部状态达到统一
组件需要设定默认值
把组件的默认值传入以后可以作为状态设定的初始值进行使用
鼠标悬停的时候需要有特定的样式
可以设定一个新的临时状态作为鼠标悬停时候修改的状态,可以使用三元运算符对悬停时的优先级状态做优先处理达到效果
重复点击实现回退或者关闭效果实现:
可以在点击的时候绑一个函数检查当前和选定id是否一致,一致就重置id让其重新渲染实现回退或者关闭
react 运作模式
组件与实例:
一个实例就是一个组件的实际物理表现,组件本身是一个函数,但是每一个组件都有自己的状态,props和生命周期,实际上,jsx被转换成多个react.create调用,一个react组件基本包含创建dom元素所需的所有信息,最后转换成一个dom,在直接调用组件的时候,react不会把其看为一个组件实例
运作方式:
调和过程 (Reconciliation)
当状态发生变化时,React 会:
创建新的虚拟 DOM 树
与旧的虚拟 DOM 树进行对比(Diff)
计算出需要更新的部分
只更新变化的部分到实际 DOM
实际上react不会直接操作dom,而是通过react-dom react-native等其他库来对于不同页面的dom进行操作
差异过程:
两种不同类型的元素会产生两种不同的树
具有稳定键的元素不变
差异过程的核心是过程中比较两种树,记录差异的位置
相同位置不同元素的情况下元素会被完全删除,包括他们的状态,然后用新的元素重建。
相同位置相同元素,状态是不变的,子元素也不会变,不会触发摧毁重建,只需要简单修改,dom本身不会修改
性能优化小技巧:
可以使用key 来对一个唯一的元素进行标识,此时元素具有稳定键就不会触发重新渲染,比方本来有两个组件,现在加入了一个新的组件,但是实际上本来两个组件本身没有变化,这个时候可以用key对其进行标记,所以有多个相同类型的子元素的时候,最好始终使用key-prop
当我们有出现相同位置相同元素但是需要重置或者更新状态的时候,也需要用key-prop用于告诉react这里需要更新
组件嵌套问题
不要在一个组件里面声明另外一个组件,否则每次父组件更新都会更新子组件的状态导致额外的性能开销和不必要的状态更新,所以组件的更新都是在函数的顶层实现的
状态更新的批处理
多个状态更新的时候不会一个一个更新,而是所有状态片段都一次性更新,所以一般而言只有重新呈现以后函数值才会更新,如果需要在重新呈现之前就使用它,可以传一个回调函数进setstate
react对事件的处理
以单击事件为例,如果有多个单击事件,react把他们捆绑到一起然后会创建一个单击事件在fiber tree的根组件上,所以实际上react对应用程序中的所有事件执行事件委托
react的实质
react本身是一个库而不是一个框架,它通过和其他库联合使用最后完成一个程序,在react的基础上,有一些延申出来的框架,如remix,next.js但react本身只是一个库
组件的生命周期
第一次呈现:以挂载
中间:重新呈现
最后:销毁/卸载
呈现逻辑和事件处理函数
事件处理函数
函数的副作用:
当一个函数去修改一些外部数据的时候就会产生一些副作用
纯函数:
不会产生副作用的函数,使用相同的输入永远会得到相同的输出
呈现逻辑
一些返回的代码块用于最终页面的呈现,比如条件渲染和列表呈现之类的。
涉及到呈现逻辑的时候,组件一定是纯函数,负责渲染的函数一定是与外界没有交流的,所以呈现逻辑不允许执行网络请求或者用dom api,也不能在呈现函数中更新状态。
Hooks
相当于react内置的一些函数是用于链接到react的内部机制,基本都是Use开头的。
Hooks只能在顶层调用,不能在条件里面调用
每次使用hooks都是用同一个调用的方式,因为实际上,hooks调用的时候会在fiber树里面创造一个链表。所以如果在条件里面调用中间的hooks不触发的话,第一个hooks仍旧是指向第二个hooks此时第三个hooks就无法实现。也可以避免对每个钩子取名
所以每次调用Hooks的时候总是以相同的顺序调用的,如果提前返回也会报错
useEffect
依赖数组:
决定这个useEffect什么时候使用,开始就用的话就用空数组
用处:
保持组件和外部系统的同步
useEffect需要用用依赖项数组来了解什么时候触发
useEffect(fn,[x,y,z])xyz变化的时候触发
useEffect(fn,[])首次挂载触发
useState
状态更新的时候往往需要等一个组件完全渲染完成才会更新,所以哪怕已经更新了状态但是组件没有成功重新渲染那么状态仍会保留在之前的状态下。
解决方法:把这个状态放到一个回调函数中,回调函数执行以后会立刻返回新的状态
当原始状态依赖于某个计算的时候,就在初始化的时候传入一个回调函数
更新状态的时候如果需要立刻使用新的状态需要使用回调函数进行更新,其实也可以所有更新都用回调函数来避免问题,更新对象和数组的时候不要去修改对象和数组,要创建一个新的对象或者数组然后传进去
useRef
相当于一个小号的state,更新state的时候会重新刷新页面但是更新Ref不会引起重新刷新,而且Ref的更新是同步而不是异步的,意味着我们可以更新以后立刻使用Ref,而且Ref是可变的。
所以Ref常常用于储存DOM元素还有其他任何不需要重新渲染的可变值