React Hooks
1.useState()
维护和更改生命周期内的变量
const [count, setCount] = useState(()=>{ return Math.random() })
2.useEffect()
state改变会触发DOM更新,用于更新完成后的操作(useEffect 的执行时机是浏览器完成渲染之后),组件卸载后的操作,以依赖数组内元素变化作为触发上述操作的条件
const [count, setCount] = useState(0)
1.
useEffect(() => {
setTimeout(()=>{setCount(cur=>cur+1)}, 1000)
})
//0 1 2 3 4 5 6 7 ...
//等价于
setTimeout(()=>{setCount(cur=>cur+1)}, 1000)
//0 1 2 3 4 5 6 7 ...
2.
useEffect(() => {
setTimeout(()=>{setCount(cur=>cur+1)}, 1000)
}, [])
//0 1
3.
useEffect(() => {
setTimeout(()=>{setCount(cur=>cur+1)}, 1000)
}, [0])
//0 1
4.
useEffect(() => {
setTimeout(()=>{setCount(cur=>cur+1)}, 1000)
}, [count<10])
//0 1
5.
useEffect(() => {
setTimeout(()=>{setCount(cur=>cur+1)}, 1000)
}, [Math.min(count, 10)])
// 0 1 2 3 4 5 6 7 8 9 10 11
//最佳实践
useEffect(() => {
setTimeout(()=>{setCount(cur=>cur+1)}, 1000)
}, [Math.min(count, 9)])
// 0 1 2 3 4 5 6 7 8 9 10
6.
useEffect(() => {
const timer = setTimeout(()=>{setCount(cur=>cur+1)}, 1000)
return () => clearTimeout(timer)
}, [Math.min(count, 9)])
// 0 1 2 3 4 5 6 7 8 9 10
7.
useEffect(() => {
setCount(cur=>cur+1)
}, [0, 1, 2])
//0 1
8.
useEffect(() => {
console.log('component did mount')
return () => console.log('component will unmount')
}, [])
3.useRef()
保存不受生命周期影响的变量和DOM元素
4.useMemo()
缓存变量,优化计算过程
5.useCallback()
缓存方法,优化方法注册
6.useContext()
分发局部全局变量
7.useReducer():
8.useLayoutEffect()
阻塞渲染的useEffect(), useLayoutEffect的执行时机是浏览器把内容真正渲染到界面之前
useCallback useMemo
useCallback 与 useMemo 一个缓存的是函数,一个缓存的是函数的返回值。useCallback 是来优化子组件的,防止子组件的重复渲染。useMemo 可以优化当前组件也可以优化子组件,优化当前组件主要是通过 memoize 来将一些复杂的计算逻辑进行缓存。
useCallback跟useMemo几乎一模一样,唯一的区别在于 useMemo 返回的是函数计算的值, 而 useCallback 返回的是函数本身。
useRef
useRef用于在组件的整个生命周期内存储持久可变对象。
useRef在改变 .current值时不会触发重新渲染。
引用更新是同步的,而状态更新是异步的并触发重新渲染。
useEffect useLayoutEffect
useEffect可能会出现出现闪屏问题
useLayoutEffect里面的callback函数会在DOM更新完成后立即执行,但是会在浏览器进行任何绘制之前运行完成,阻塞了浏览器的绘制
createRef useRef
React.createRef用于class组件:ref属性用来获取DOM元素的节点和获取子组件的实例
React.useRef用于函数组件:可以保存任何类型的值(dom、对象等任何可辨值),ref对象的值发生改变之后,不会触发组件重新渲染。
React setState 是同步异步
React控制之外的事件中调用setState是同步更新的。比如原生js绑定的事件,setTimeout/setInterval等。
React封装的事件,比如onChange、onClick、onTouchMove等,这些事件处理程序中的setState都是异步处理的。
强制更新
const [, setChange] = useState()
setChange({})