React 文档重新学习


前言

2024 了, React 也升级到了 v18, 底层的渲染模式也更新到了 concurrent mode, 重新学习一下官方文档。

文档中的一些最佳实践

  • 当你不确定某些代码应该放在 Effect 中还是事件处理函数中时,先自问 为什么 要执行这些代码。Effect 只用来执行那些显示给用户时组件 需要执行 的代码。
  • 如果一个值可以基于现有的 props 或 state 计算得出,不要把它作为一个 state,而是在渲染期间直接计算这个值。
  • 尽可能在渲染期间进行计算,以及在事件处理函数中调整 state
  • 如果没有涉及到外部系统(例如,你想根据 props 或 state 的变化来更新一个组件的 state),你就不应该使用 Effect。
  • 昂贵的计算属性的时候,使用 useMemo 优化。总耗时达到了一定量级(比方说 1ms 或更多),那么把计算结果记忆(memoize)起来可能是有意义的。
  • “状态提升” 允许父组件通过切换自身的 state 来完全控制 Toggle 组件。这意味着父组件会包含更多的逻辑,但整体上需要关心的状态变少了。每当你尝试保持两个不同的 state 变量之间的同步时,试试状态提升!
  • 既然子组件和父组件都需要相同的数据,那么可以让父组件获取那些数据,并将其 向下传递 给子组件

使用 useEffect 的思考模式变化

不要考虑组件的渲染角度, 而是要从 effect 的角度思考:在组件生命周期的每个阶段,Effect 执行了不同的操作

useEffect 开发环境会被执行两次

React 在开发环境中,会重新挂载组件一次,以验证你是否正确地实现了清理函数, 即使依赖是 []

props 变化的时候,重置 state

  • 重置所有的 state, 就相当于重新渲染一个组件, 这个场景, 应该使用外部组件渲染的时候,传递一个 key, 而不是使用 useEffect 监听 props 变化, setState 清空。
  • 有条件的重置部分 State, 比如选中状态,建议在渲染期间直接比较 prevState 和当前 props 的值,然后**直接 setXXXX ** 修改 state.useState – React 中文文档, 这种在渲染组件渲染过程中,直接调用 setXXX 的方法,在组件渲染的时候, 会自动重新渲染,避免当前多余的渲染操作。
    • 最佳的情况,是记录下渲染状态关联的状态, 比如 selectedId, 如果 props 变化, 只需要去判断是否存在对应的 id , 决定是否勾选

组件首次加载的数据,比如 user 信息

  • useEffect((), []) 的方式触发,这种是组件加载的时候,就会调用的。
  • 但如果我们期望的是应用加载时执行一次的动作,必须通过引入顶层变量来记录。或者在组件外部执行。

订阅外部 store, 比如 pub-sub 模式

比如订阅 IPC, 或者 windows 的一些事件。比如订阅 是浏览器的 navigator.onLine API, 常见的写法:

function useOnlineStatus() {
  // 不理想:在 Effect 中手动订阅 store
  const [isOnline, setIsOnline] = useState(true);
  useEffect(() => {
    function updateState() {
      setIsOnline(navigator.onLine);
    }

    updateState();

    window.addEventListener('online', updateState);
    window.addEventListener('offline', updateState);
    return () => {
      window.removeEventListener('online', updateState);
      window.removeEventListener('offline', updateState);
    };
  }, []);
  return isOnline;
}

文档说不是好的写法。。。。而是应该使用 useSyncExternalStore – React 中文文档 这个新的 API.

数据请求

不要自己封装了, 而是使用请求库, 比如 react-query, swr.