React Hooks应该避免的5个常见错误
Hook 是 React 16.8 的新增特性,它可以让你在不编写 class 的情况下使用 state,生命周期以及其他的 React 特性,非常受开发者的喜爱。
不过,React Hooks作为高级特性,使用的时候也会有一些 Hook 规则 和注意事项。
本文中,我将讨论在构建 React 应用程序时应避免的 5 个常见 React Hooks 错误
错误1:更改Hooks调用顺序
只在最顶层使用Hook ,不要在循环,条件或嵌套函数中调用 Hook, 确保总是在你的 React 函数的最顶层以及任何 return 之前调用他们。遵守这条规则,你就能确保 Hook 在每一次渲染中都按照同样的顺序被调用。这让 React 能够在多次的
useState
和useEffect
调用之间保持 hook 状态的正确。(如果你对此感到好奇,我们在下面会有更深入的解释。)
上面是官网的原话,下面我们创建一个场景,解释一下。
我创建了一个基本的 React 组件,组件有一个下拉列表,从列表中选择一个人并显示人员的数据,看错误代码:
乍一看,很完美,但是控制台会抛出错误。因为useState
和useEffect
并不是在第一个return 之前调用的。看一下效果图:
如何改正呢?思考三分钟...
其实很简单,只需要把 useState和useEffect的调用顺序放到 函数体的最上面即可。看图:
把 useState和useEffect的调用顺序放到 函数体的最上面,控制台错误消失了。
错误2:不必要的重新渲染
在组件中,可以使用useState
Hook 进行状态处理。虽然它非常简单,但如果使用不当,可能会出现意想不到的问题。
例如,假设一个组件有两个按钮。第一个按钮将触发一个计数器,第二个按钮将根据当前计数器状态发出请求。
上面的组件运行起来没问题,控制台也没有报错。但是,由于我们在渲染阶段没有使用 counter,每次点击计数器按钮时都会出现不需要的重新渲染。
假如,你需要一个变量,它既能保持状态值(state),又能不触发重新渲染,useRef
是更好的选择。改进一下代码:
错误3:通过 useEffect 处理 Action
使用 useEffect
Hook 监听 prop
或state
变化之后处理一任务。但是,在某些情况下,它会使事情变得更加复杂。
例如:有一个组件获取数据列表并将其渲染到页面上
fetchPersons
组件初始化的时候,第一个useEffect
调用了apiCall
函数。 在所有的条件的都满足的情况下,第二个useEffect
将会调用onSucces
方法。
可以看出,apiCall
和 onSuccess
被割裂在两个Hook里面,这样会有两个问题,一是不能保证只有成功了才去触发onSuccess,而是代码可读性比较差,后期维护比较困难。
改进方案是把onSuccess
放到apiCall
成功的回调里面,保证只有请求成功的情况下载去调用。如图:
错误4:丢失useEffect的依赖
useEffect
Hook 是 React 中最常用的 Hook 之一,默认情况下它总是在每次重新渲染时运行。在某些情况下,每次渲染后都执行清理或者执行 effect 可能会导致性能问题。
如果某些特定值在两次重渲染之间没有发生变化,你可以通知 React 跳过对 effect 的调用,只要传递数组作为 useEffect
的第二个可选参数即可:
useEffect(() => {
showCount(count)
}, [count]); // 仅在 count 更改时更新
看一下 React官网解释:
如果你要使用此优化方式,请确保数组中包含了所有外部作用域中会随时间变化并且在 effect 中使用的变量,否则你的代码会引用到先前渲染中的旧变量。参阅文档,了解更多关于如何处理函数以及数组频繁变化时的措施内容。
如果想执行只运行一次的 effect(仅在组件挂载和卸载时执行),可以传递一个空数组(
[]
)作为第二个参数。这就告诉 React 你的 effect 不依赖于 props 或 state 中的任何值,所以它永远都不需要重复执行。这并不属于特殊情况 —— 它依然遵循依赖数组的工作方式。
如果你传入了一个空数组(
[]
),effect 内部的 props 和 state 就会一直拥有其初始值。尽管传入[]
作为第二个参数更接近大家更熟悉的componentDidMount
和componentWillUnmount
思维模式,但我们有更好的方式来避免过于频繁的重复调用 effect。除此之外,请记得 React 会等待浏览器完成画面渲染之后才会延迟调用useEffect
,因此会使得额外操作很方便。
我们推荐启用
eslint-plugin-react-hooks
中的exhaustive-deps
规则。此规则会在添加错误依赖时发出警告并给出修复建议。
看一下面一个例子:
可以看出,点击了按钮四次,但是showCount方法,只输出了一次结果。
正确的做法是,添加count依赖。
useEffect(() => {
showCount(count)
}, [count]); // 仅在 count 更改时更新
错误5:使用了过期的State
先看一个例子:多次调用更新state的方法。
多次更改 useState,会被合并成一次,因为 state 只在组件首次渲染的时候被创建。在下一次重新渲染时,useState
返回给我们当前的 state。
如果就像更改三次,怎么办呢?答案是useState参数使用函数的方式
参考链接
Common React Hooks Mistakes You Should Avoid
最后总结
在使用具有高级和自定义功能的 React Hooks 时往往会犯一些错误。在本文中,讨论了在使用 React Hooks 时应避免的 5 个常见错误。
本人水平有限,如果对本文有任何建议或者发现了错误,欢迎在在评论区分享。
谢谢阅读!!!
转载自:https://juejin.cn/post/7053484420782620709