- 在不写class的情况下使用state以及生命周期等其它特性
- 定义一个数组里面有一个参数和修改参数的方法 = useState(),而这个参数相当于state
- 优点:没有破坏性改动—完全可选,100%向后兼容
- 动机:便于复用状态逻辑和理解
State Hook:
- 声明多个state变量: 可以在一个组件中多次使用State Hook
Effect Hook:
- “副作用”: 在 React 组件中执行过数据获取、订阅或者手动修改过 DOM
- useEffect 就是一个 Effect Hook,给函数组件增加了操作副作用的能力=挂载+更新+卸载的用途
- 通过返回一个函数来指定如何“清除”副作用
1
2
3
4
5
6useEffect(() => {// 每次渲染都调用
ChatAPI.subscribeToFriendStatus(props.friend.id,handleStatusChange);//挂载+更新
return () => {
ChatAPI.unsubscribeFromFriendStatus(props.friend.id,handleStatusChange);//卸载
};
}); - 同一组件可以多次使用
使用规则
- 只能在函数最外层调用 Hook
- 只能在 React 的函数组件中调用 Hook 和 自定义的 Hook 中
自定义Hook
- 封装一个组件里面包含State Hook 和Effect Hook且包含了一些共同的方法
- 其它组件可以调用它来使用这个方法,每一个组件使用hook的state都是独立
其它Hook
- useContent()不使用组件嵌套就可以订阅React的Content
- useRenduser()可以通过reducer来管理组件本地的复杂state
使用State Hook
- Hook在class内部时不起作用的
- 例:const [count, setCount] = useState(0) //说明count的初始值为0
- 存储几个state变量就要调用几次useState
- 在函数中使用,可以直接用count:
<p>{count}</p>
- 更新:onClick = {() => setCount(count+1)},在函数直接setCount()和this.setState()
使用Effect Hook
- 不需要清除的effect:
- 在 React 更新 DOM 之后运行一些额外的代码
- 传递给 useEffect 的函数在每次渲染中都会有所不同,防止过期
- 需要清除的effect:
- 订阅外部数据源,防止内存泄露
- 在订阅的时候return() => { 模块.un方法(参数,方法)}
- 使用多个Effect实现关注点分离
- 挂载和更新内容不同,挂载和卸载内容不同
- 使用多个useEffect把相同的内容放在一起
- 每次更新的时候都要运行Effect:防止显示的还是没更新前的状态
- 订阅和清除顺序按顺序执行
- 通过跳过 Effect 进行性能优化
- 如果某些特定值在两次重渲染之间没有发生变化,跳过对 effect 的调用,只要传递数组作为useEffect 的第二个可选参数即可:
1
2
3useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // 仅在 count 更改时更新
Hook规则
- 只在最顶层使用 Hook:不要在循环,条件或嵌套函数中调用 Hook
- 只在 React 函数中调用 Hook
自定义组件
- 在 React 中有两种流行的方式来共享组件之间的状态逻辑: render props 和高阶组件,自定义 Hook
useDeferredValue
在新内容加载期间显示旧内容,延迟更新 UI 的某些部分
const deferredValue = useDeferredValue(value)
- 如在input中流程先输入 -> 开始渲染 -> 渲染完成前输入 -> 渲染中断 -> 执行新的渲染,在渲染完前这期间可以随时中断渲染
- 这个value可以使用useState的变量
useOptimistic
const [optimisticState, addOptimistic] = useOptimistic(state, updateFn);
- 接受一个状态state,以及加工函数updateFn,其中updateFn在state更新时返回你想要的乐观结果,updateFn = (currentState, optimisticValue) => {}