React 学习的10个疑问点

312 阅读3分钟

哪个版本的 React 包含了 Hook?

从 16.8.0 开始,React 在以下模块中包含了 React Hook 的稳定实现:

  • React DOM
  • React Native
  • React DOM Server
  • React Test Renderer
  • React Shallow Renderer

请注意,要启用 Hook,所有 React 相关的 package 都必须升级到 16.8.0 或更高版本。如果你忘记更新诸如 React DOM 之类的 package,Hook 将无法运行。

React Native 0.59 及以上版本支持 Hook。

有什么是 Hook 能做而 class 做不到的?

Hook 提供了强大而富有表现力的方式来在组件间复用功能。通过 「自定义 Hook」。这篇来自一位 React 核心团队的成员的 文章 则更加深入地剖析了 Hook 解锁了哪些新的能力。

我应该使用 Hook,class,还是两者混用?

你不能在 class 组件内部使用 Hook,但毫无疑问你可以在组件树里混合使用 class 组件和使用了 Hook 的函数组件。不论一个组件是 class 还是一个使用了 Hook 的函数,都只是这个组件的实现细节而已。

Hook 能否覆盖 class 的所有使用场景?

Hook 设定的目标是尽早覆盖 class 的所有使用场景。目前暂时还没有对应不常用的 getSnapshotBeforeUpdategetDerivedStateFromError 和 componentDidCatch 生命周期的 Hook 等价写法。目前 Hook 还处于早期阶段,第三方的库无法全部兼容 Hook。

Hook 会替代 render props 和高阶组件吗?

render props 和高阶组件只渲染一个子节点,(例如,一个虚拟滚动条组件或许会有一个 renderItem 属性,或是一个可见的容器组件或许会有它自己的 DOM 结构)。但在大部分场景下,Hook 足够了,并且能够帮助减少嵌套。

Hook 对于 Redux connect() 和 React Router 等流行的 API 来说,意味着什么?

React Redux 从 v7.1.0 开始支持 Hook API 并暴露了 useDispatch 和 useSelector 等 hook。 React Router 从 v5.1 开始支持 hook, 其它第三库也将即将支持 hook。

在依赖列表中省略函数是否安全?

function Example({ someProp }) {
  function doSomething() {
    console.log(someProp);  }

  useEffect(() => {
    doSomething();
  }, [依赖项最好填下]); // 🔴 这样不安全(它调用的 `doSomething` 函数使用了 `someProp`)}

假如依赖项不写的话,useEffect在判断是否执行更新的函数时,就有可能不执行或者一直执行,会消耗代码性能。

我该如何实现 shouldComponentUpdate?

你可以用 React.memo 包裹一个组件来对它的 props 进行浅比较:

const Button = React.memo((props) => {
  // 组件 对比新旧依赖项的变化来判断显示不同的组件
});

Hook 会因为在渲染时创建函数而变慢吗?

在现代浏览器中,闭包和类的原始性能只有在极端场景下才会有明显的差别。

  • Hook 避免了 class 需要的额外开支,像是创建类实例和在构造函数中绑定事件处理器的成本。
  • 符合语言习惯的代码在使用 Hook 时不需要很深的组件树嵌套。这个现象在使用高阶组件、render props、和 context 的代码库中非常普遍。组件树小了,React 的工作量也随之减少。

在 React 中使用内联函数对性能的影响,与每次渲染都传递新的回调会如何破坏子组件的 shouldComponentUpdate 优化有关。Hook 从三个方面解决了这个问题。

// 除非 `a` 或 `b` 改变,否则memoizedCallback不会变 doSomething就不会执行
const memoizedCallback = useCallback(() => {  
   doSomething(a, b);
}, [a, b]);
  • useMemo Hook 使得控制具体子节点何时更新变得更容易,减少了对纯组件的需要。

  • useReducer Hook 减少了对深层传递回调的依赖。