# hook
函数组件中用来代替生命周期的函数。
以下生命周期没有对应的hook。
- getDerivdStateFromProps()
- getSnapShotBeforeUpdate()
- getDerivdStateFromError()
- componentDidCatch()
# 为什么需要 hook
类组件中逻辑复用通常使用需要使用 HOC 或者 render props。 但是 HOC 或者 render props 会增加不必要的DOM节点。
逻辑分散在各个生命周期函数中,比如事件的监听和取消。
this指向问题 就是事件的handler中this问题。要么使用bind,要么使用public class field.
# useState()
用来代替 state 和 setState()
const [state, setState] = useState(initialState | ()=>{} );
参数:
useState()可以传入默认值或者一个用来生成默认值的函数。
当传入函数时,这个函数只会执行一次。当默认值计算比较耗时时,建议使用。
返回值:
第一个是初始值。
第二个是更新初始值的函数。这个更新函数和this.setState()的参数一样, 可以传值或者函数。
什么时候使用函数:
setState(prevState => prevState + 1)
- 当更新state的值依赖上一次的state的值时。
- 当在setTimeout或在callback中调用setState()时。
# useEffect()
副作用,用来代替 componentDidMount, componentDidUpdate, componentWillUnmount.
useEffect(()=>{
// 清除函数
return ()=>{}
}, [deps])
参数:
需要执行的函数()=>{}
重新运行的依赖
- 当不穿依赖时,在每次渲染都会运行。
- 当传入 []时,只在componentDidMount时运行。
- 当传入 [a,b,c]时,只在a或者b或者c变化时运行。
如果执行函数中返回清除函数,清除函数会在组件重新渲染或者卸载时运行。
# useLayoutEffect()
useEffect 在浏览器渲染完成后执行,不会阻塞浏览器更新屏幕,是异步的。
useLayoutEffect 在浏览器渲染前执行,是同步的。因此useLayoutEffect 总是比 useEffect 先执行。
# Memo api
Memo(fn)
只应用于函数组件,用来代替 shouldComponentUpdate()
# useMemo()
缓存函数的执行结果。
useMemo(()=>{},[deps])
参数:
- 需要执行的函数()=>{}
- 重新运行的依赖
useMemo() 不是用来代替生命周期函数的。 它的作用是性能优化的。比如优化耗时计算,传递函数给子组件。
# useCallback()
缓存函数fn(不会执行这个函数)
useCallback(fn, [deps])
等同于
useMemo(()=>fn, [deps])
都是用来性能优化的。当父组件传递 函数 给子组件时用。
# useRef()
const refContainer = useRef(initialValue);
参数: initialValue
返回值:
useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。 返回的 ref 对象在组件的整个生命周期内保持不变。
作用:
代替只能在类组件中使用的 React.createRef()。 用来获取DOM元素。
用来保存多次渲染不变的变量,相当于实例字段。
不同于state的是,改变ref.current的值不会引起重新渲染。
- 实现 componentWillReceiveProps。也就是监控props的变化。
const prevProps = useRef(currentProps);
if(prevProps !== currentProps){
prevProps.current = currentProps;
}
# useContext()
# useReducer()
和Redux中的reducer一样,不过Redux的reducer控制的是store中的state。 useReducer控制的是组件中的state。
# 自定义hook
- 可以返回JSX
- 可以返回 [value, setValue] 等。
# hook 规则
- 只能在函数组件中使用
- 只能写在函数组件顶层,不能写在循环,if语句中。
- 自定义hook要以use开头
- 使用eslint-plugin-react-hooks检查
"eslintConfig": {
"extends": "react-app",
"plugins": [
"react-hooks"
],
"rules": {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
}
},