You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constTemplate=()=>{constgetStandardTemplateList=async()=>{constres: any=awaitAPI.getStandardTemplateList()if(!res.success)return;const{ data }=res;setCascaderOptions(data);getDefaultOption(data[0])}useEffect(()=>{getStandardTemplateList()},[getStandardTemplateList])}
constgetStandardTemplateList=async()=>{constres: any=awaitAPI.getStandardTemplateList()if(!res.success)return;const{ data }=res;setCascaderOptions(data);getDefaultOption(data[0])}constTemplate=()=>{useEffect(()=>{getStandardTemplateList()},[])}
Hooks
Hook是React16.8的新增特性,能够在不写class的情况下使用state以及其他特性。
动机
hook规则
不要再循环/条件/嵌套函数中使用
函数组件和类组件的不同
函数组件能够捕获到当前渲染的所用的值。
点击查看示例
对于类组件来说,虽然props是一个不可变的数据,但是this是一个可变的数据,在我们渲染组件的时候this发生了改变,所以this.props发生了改变,因此在this.showMessage中会拿到最新的props值。
对于函数组件来说捕获了渲染所使用的值,当我们使用hooks时,这种特性也同样的试用于state上。
点击查看示例
如果我们想跳出'函数组件捕获当前渲染的所用值‘这个特性,我们可以采用ref来追踪某些数据。通过ref.current可以获取到最新的值
useEffect
useEffect能够在函数组件中执行副作用操作(数据获取/涉及订阅),其实可以把useEffect看作是componentDidMount/componentDidUpdate/componentWillUnMount的组合
第一个参数是一个callback,返回destory。destory作为下一个callback执行前调用,用于清除上一次callback产生的副作用
第二个参数是依赖项,一个数组,可以有多个依赖项。依赖项改变,执行上一个callback返回的destory,和执行新的effect第一个参数callback
对于useEffect的执行,React处理逻辑是
采用异步调用
的,对于每一个effect的callback会像setTimeout回调函数一样,放到任务队列里面,等到主线程执行完毕才会执行。所以effect的回调函数不会阻塞浏览器绘制视图相关的生命周期替换方案
componentDidMount替代方案
componentDidUnmount替代方案
componentWillReceiveProps替代方案
其实两者的执行时机是完全不同的,
一个在render阶段,一个在commit阶段
useEffect会初始化执行一次,但是componentWillReceiveProps只会在props变化时执行更新
componentDidUpdate替代方案
useEffect 和 componentDidUpdate 在执行时期虽然有点差别,
useEffect 是异步执行,componentDidUpdate 是同步执行
,但都是在 commit 阶段在useEffect中[]需要处理什么
React官网FAQ这样说
只有当函数(以及它所调用的函数)不引用 props、state 以及由它们衍生而来的值时,你才能放心地把它们从依赖列表中省略,使用eslint-plugin-react-hooks帮助我们的代码做一个校验
点击查看详细示例
是否应该把函数当做effect的依赖
第一个简单的解法,对于某些只在useEffect中使用的函数,直接定义在effect中,以至于能够直接依赖某些state
假如我们需要在很多地方用到我们定义的函数,不能够把定义放到当前的effect中,并且将函数放到了第二个的依赖参数中,那这个代码将就进入死循环。因为函数在每一次渲染中都返回一个
新的引用
针对这种情况,如果当前函数没有引用任何组件内的任何值,可以将该函数提取到组件外面去定义,这样就不会组件每次render时不会再次改变函数引用。
如果说当前函数中引用了组件内的一些状态值,可以采用useCallBack对当前函数进行包裹
useCallback
React官网定义
返回一个memoized回调函数,该回调函数仅在某个依赖项改变时才会更新
点击查看详细示例
React.memo是通过记忆组件渲染结果的方式来提高性能,memo是react16.6引入的新属性,通过
浅比较
(源码通过Object.is方法比较)当前依赖的props和下一个props是否相同来决定是否重新渲染;如果使用过类组件方式,就能知道memo其实就相当于class组件中的React.PureComponent,区别就在于memo用于函数组件。useCallback和React.memo一定要结合使用才能有效果。使用场景
useMemo
React官网定义
返回一个 memoized 值
仅会在某个依赖项改变时才重新计算memoized值,这种优化有助于避免在每次渲染时都进行
高开销的计算
useCallback(fn, deps) 相当于 useMemo(() => fn, deps)
对于实现上,基本上是和useCallback相似,只是略微有些不同
使用场景
两个 hooks 内置于 React 都有特别的原因:
引用相等
当在React函数组件中定义一个对象时,它跟上次定义的相同对象,引用是不一样的(即使它具有所有相同值和相同属性)
大多数时候,你不需要考虑去优化不必要的重新渲染,因为优化总会带来成本。
昂贵的计算
计算成本很高的同步计算值的函数
总结
本文介绍了hooks产生动机、函数组件和类组件的区别以及useEffect/useCallback/useMemo等内容。重点介绍了useEffect的生命周期替换方案以及是否把函数作为useEffect的第二参数。
The text was updated successfully, but these errors were encountered: