要说hooks,首先得说说类组件和函数组件的区别
类组件:本质是OOP——面向对象编程,有继承,有状态,也有生命周期
- 大型组件很难拆分和测试(仅一个按钮组件的逻辑就已经很重了,再加上多个类层层继承就变成了一个复杂容器)
- 组件类引入了复杂的render-props和高阶组件,组件与组件之间耦合太高,复用性就降低了;
- 以类的形式编写就会导致this模糊的问题,每次都需要再constructor中用bind绑定函数;
- 业务逻辑分散在组件的各个方法或者生命周期中,可能会出现一个生命周期里,几个不同逻辑的函数,也可能出现几个不同的生命周期中,都需要操作相同的逻辑这两种现象。这些都会导致功能不内聚,也没有做到关注点分离。
函数组件:本质是面向函数编程(给我一个参数,我返回一个值),无状态,无生命周期,纯粹、简单易测试且轻量
react设计模式倾向于组合优于继承,只是需要将组件与组件简单组合,而不需要它们之间有太多继承那样复杂的父子联系,而函数组件就十分符合设计思想,但函数组件的操作十分有限,react-hooks应运而生,有了它的加持,函数组件也可以做到全功能了——它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
react-hooks就是用来解决这些副作用的(纯函数只能进行数据计算,我们把不涉及数据计算的操作,比如存数据、改变应用状态的行为叫副作用),hooks故名思意——钩子,我函数组件需要用到什么操作,就从外部把它钩进来自己使用,每种钩子用usexxx来定义。
在使用它的时候,忘记生命周期那一系列的思维模式,你会更好理解它。
下面列举几种常用的钩子来看看它有什么作用(这里只做简单总结,建议先熟悉它的用法再来看看,详细用法参见官网reactjs.org/docs/hooks-…)
- useState:状态钩子
- 它接收一个初始状态作为参数,返回一个数组[变量(指向状态值),函数(用来更新状态)]
- useContext:共享状态钩子
- 在需要共享的组件外部创建并包裹一个context,注入要共享的值和对象,然后在组件中解构出这个值
- useEffect:副作用钩子
- 将一种副作用放入一个useEffect,做到一个useEffect只关注一个逻辑(符合关注点分离),避免在类组件中逻辑重复或过于分散的问题
- useEffect(()=>{},[]),第一个函数中放副作用(获取数据、事件监听或订阅、改变dom),第二个参数是它的依赖项——只要依赖项发生变化就执行useEffect,如果第二个参数传空数组,那就没有依赖项,只在组件加载进入dom后执行一次,如果省略第二个参数,每次渲染都会执行Effect
- 我们需要在组件卸载的时候取消事件的订阅防止内存泄露——在副作用函数中返回一个函数来清理事件,这个函数在每次副作用函数执行之前都会执行清理上一次的副作用
- 如果你的页面出现闪动,使用这个钩子——useLayoutEffect
如果两个组件需要相同的逻辑,那就可以自定义一个钩子把这些逻辑装起来,需要用到的组件把它钩进去即可。
参考: