关于React Hooks,你不得不知的事 (2)

可以看到,我们利用副作用钩子很好地实现了原本的生命周期方法。通常我们会利用组件的生命周期函数去获取数据,操作DOM等,而这些操作都被称作副作用(side effect)。这些副作用逻辑一般都比较复杂,也是bug频发的地段。 所以我们可以针对每一段逻辑单独使用一个Effect钩子,便于后期维护和调试。

在使用过程中,useEffect方法需要传入两个参数,第一个参数是回调函数:这个回调函数会在每次组件渲染后执行,包括初始化渲染以及每次更新时。另一个参数,则是状态依赖项(数组形式),一旦检测到依赖项数据变动,组件会更新,并且回调函数都会被再次执行一遍,从而实现componentDidUpdate的功能。如果你传入一个空依赖,就能实现原来componentDidMount的效果,即只会执行一次。回调函数中如果返回的是闭包,这个返回的闭包函数将会在组件重新渲染前执行,所以你可以在这个位置做一些清理操作,从而实现componentWillUnmount的功能。

还有要注意的是componentWillMount和componentWillUpdate两个生命周期方法在新版本的React中已经不推荐使用了,具体原因可以查看这里。

至此,我们就学会如何利用Effect钩子在函数式组件中实现所有生命周期方法,从而管理我们的应用了。

自定义Hook

重用和抽象一直都是编程中要解决的问题。我们可以自己封装想要的Hook, 从而实现代码逻辑的重用和抽象。

封装自定义hook其实很简单,就是包装一个自定义函数,然后根据功能将其状态和对应的effect逻辑封装进去:

export const useFetch = (url, dependencies) => { const [isLoading, setIsLoading] = useState(false); const [response, setResponse] = useState(null); const [error, setError] = useState(null); useEffect(() => { setIsLoading(true); axios.get(url).then((res) => { setIsLoading(false); setResponse(res); }).catch((err) => { setIsLoading(false); setError(err); }); }, dependencies) return [isLoading, response, error]; } 复制代码

这里我们简单地封装了一个请求数据的Hook,使用方法跟其他Hook类似,直接调用就可以了:

export const Person = () => { const [isLoading, response, error] = useFetch("http://example.com/getPersonInfo", []); return ( <div> {isLoading ? <div>loading...</div> : ( error ? <div> There is an error happened. {error.message} </div> : <div> Welcome, {response.userName} </div> ) } </div> ) } 复制代码 注意事项

在使用Hooks的过程中,需要注意的两点是:

不要在循环,条件或嵌套函数中调用Hook,必须始终在React函数的顶层使用Hook。这是因为React需要利用调用顺序来正确更新相应的状态,以及调用相应的钩子函数。一旦在循环或条件分支语句中调用Hook,就容易导致调用顺序的不一致性,从而产生难以预料到的后果。

只能在React函数式组件或自定义Hook中使用Hook。

为了避免我们无意中破坏这些规则,你可以安装一个eslint插件:

npm install eslint-plugin-react-hooks --save-dev 复制代码

并在配置文件中使用它:

{ "plugins": [ // ... "react-hooks" ], "rules": { // ... "react-hooks/rules-of-hooks": "error" } } 复制代码

这样,一旦你违法上述这些原则,就会获得相应的提示。

总结

本文介绍了React Hook的使用方式,并通过几个简单的例子演示了如何在函数式组件中进行状态管理和生命周期管理。官方目前提供了很多基础的Hook,如useContext, useReducer, useMemo等,大家可以酌情在项目中使用。

参考资料

https://reactjs.org/docs/hooks-reference.html

——本文首发于个人公众号,转载请注明出处———

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwxxyg.html