React18新文档 beta.reactjs.org/
状态更新
- 组件的Key和Type为fiber结点打标签,更新,删除,新增,其中更新操作是复用fiber结点的状态和dom,在旧数据上进行更新状态和dom,明确组件的Key可以使React的Diff算法更好的判断组件是否需要更新,同时可以避免不必要的Effect使用。
- useState的使用,初始值只用于第一次挂载;避免冗余状态,单一数据源。
- useState原理官方简化版本
- 状态更新是异步的,进queue进行更新(v18 完全异步),旧版本不在React周期内的状态更新是同步。
- 状态批处理注意状态快照的概念。
- 将组件视为受控和非受控。区别在于父组件是否可以控制子组件状态,父组件可以控制子组件,子组件即为受控组件;父组件无法控制子组件,子组件内部有本地状态,子组件即为非受控组件。
逃生舱
逃生仓是指,提供一种方式,这种方式可以处理React内部管理以外的操作,即副作用,如DOM API获取,网络请求和第三方库的调用等等。
useRef
在多次渲染中,总是需要返回相同的对象,就是一个常规的js对象。- ref与直接定义在组件外部的普通变量还是有区别的,ref还是在组件内部,只是不涉及渲染相关,组件外部的普通变量可以被多个组件共享。
React.forwardRef()
可以转移当前ref
引用给props
中的ref
,即父组件可以通过此api拿到子组件的dom
.useImperativeHandle
可以限制父组件拿到子组件dom的内容。flushSync
这将指示 React 在包裹在其中的代码执行后立即同步更新 dom- 避免更改由 React 管理的 DOM 节点
- refs 用于非破坏性操作,例如定时器id、聚焦、滚动或拿到 DOM 元素信息;渲染时不要对dom进行操作。
- Effect与Event的不同,Effect是渲染后不是由特定事件引起的副作用,Event是调用事件时发生的副作用。
- Effect用于同步React以外的系统,内部的逻辑是**响应式(响应值的变化会进行重新渲染)**的。
- Event响应特定的交互,内部的逻辑是**非响应式(响应值的变化不会进行重新渲染)**的。
- Effect还可以终止上一个请求,设置一个flag,useEffect的清除函数设置为true。
- 避免在Effect中,当props变更时,变更state的值。如果这样操作,这会使得页面渲染两次,一次是props变更,一次是Effect中state变更(Effect在页面完成渲染之后才调用)。可考虑解决方法:使用键重置所有状态或在渲染期间计算所有内容 。
- Effect有独立的生命周期,与组件生命周期不同。
- 每个Effect应该是独立的一段同步逻辑。
- 尽可能避免对象和函数作为Effect依赖项。
- 尽量避免disable linter.
- 避免创建和使用自定义的‘生命周期’Hooks 作为
useEffect
API 本身的替代品,因为自定义的’生命周期‘HooksuseMount
不能很好地融入 React 范式。
一些官方的新的自定义Hook
useEvent
将渲染副作用与事件调用分开,提取非响应式的逻辑,可以拿到最新的值,但不会引起重新渲染,返回一个事件函数,所有 Event 函数都是*稳定的:*它们在重新渲染时永远不会改变,所以Event函数放入Effect中不会改变。目前只支持在Effect中使用,其他自定义hook不能引入,此hook避免了对依赖数组的欺骗。- 官方定时器demo
useImperativeHandle
useSyncExternalStore