react hooks in practice
useState
和 react 的 this.state 是一个东西
useEffect
在 component.DidMount 和 componnet.DidUpdate 这两个生命周期内执行。如果在useEffect中有return的话,return部分在componnetWillUnmount阶段调用。
关于 useEffect 第二个参数的三种情况:
codesandbox
- 不写。视情况而定,会发生语法报错,说:缺失依赖值,可能会导致对依赖的无限查找。不写就是默认对你所有用到的值变化的时候执行。
- 空数组[]。当useEffect 中用到了依赖值,却设置了空依赖列表,会发生报错,强制忽略报错,可以用来阻止代码执行。
- 正常情况下的所用值形成的依赖列表。
useEffect 的应用:
- 有些在浏览器中才能使用的,而在build阶段不可以使用的,比如
localstorage
, react router中的location.state.xxx
,这部分的代码可以写为useEffect(...some code...,[])
- 结合 useRef 写一个自定义hook储存 previous state。(下文中的demo还显示了 useRef 和 组件外部变量的应用区别。)
codesandbox - 设置定时器,对input输入内容的防抖。
oi-wiki-search.js
codesandbox
useContext
当一个较深层次的子组件要使用父组件的一些值的时候,使用useContext可以避免props层层传递的累赘,而直接在context.provider包裹下的组件中,使用context.consumer或者useContext获取顶层父组件的值(provider value),而不单单是上一层父组件的值。
可以应用在主题和语言设置上。
intl context provider部分
intl context consumer部分
intl useContext 部分
或许可以考虑写一个单独demo出来??
useCallback 、 useMemo and React.Memo
这三者都有很大的相似性。react 在对props进行相等性检查时,对于相同值但是代码来源不同的数组和对象的对比结果会为false,这就导致很多不必要的重计算和重渲染,这三个API都可以用来处理这个问题。
1 | //相等性检查 |
在下面这个demo可以看到,options的值没有变化,可是由于js的工作机制,在上层组件(在demo中上层组件是App)发生更新时,每次传入 Apple 组件的参数,都被认为是新的,useEffect的回调函数进行了re-run,(re-render了吗?可由devtools监测到HTML元素),并且在codesandbox也可以看到(react-hooks/exhaustive-deps)eslint给出的使用useMemo的修改建议。
1 | import React,{useEffect, useState} from "react"; |
但是参看博客,任何性能优化都具有代价,在进行使用前都应该测量一下,性能优化的代价是不是足以抵销重计算的时间。
useRef
useRef 会在每次渲染时返回同一个 ref 对象,并且变更 .current 属性的变化不会引发组件重新渲染。
官方文档的应用示例:阻止input框不必要的rerender
1 | function App() { |