react 函数式组件为了能够保存状态引入了hooks。
useState不能直接修改返回值,执行setXXX会让整个函数组件从头执行生成新的上下文,所以需要配合useMemo,useCallback等api使用。
setXXX修改步骤:
- 将传入setxxx后续操作,放到fiber节点的hooks链对应的hook节点的任务队列;
- 重新执行组件函数,基于原hook链按顺序生成新的hook链并给被hooks包裹的变量赋值,执行到有操作的setxxx hook节点,执行操作后再赋值;
- 基于当前上下文重新渲染函数组件;
1. setxxx
异步更新
2. setxxx
状态复用
-
传参变量(以最后一次赋值为准)
const [count, setCount] = useState(0); function handleCount() { setCount(count + 2); setCount(count + 1); } // 页面最终展示 1
-
传参函数(对状态进行复用)
const [count, setCount] = useState(0); function handleCount() { setCount(pre => pre + 2); setCount(pre => pre + 1); } // 页面最终展示 3
3. 内部浅拷贝优化
const [count, setCount] = useState(["a", "b"]);
function handleCount() {
let temp = count; // 可解构生成新对象[...count]
temp.push("234");
setCount(temp);
}
// 不会出发页面优化
在进行setXXX时内部会进行浅比较 if (is(eagerState, currentState)) {return;}
,相等不会触发页面更新。
总结:
- setXXX属于异步更新;
- 传参最好是函数,这样再同步调用多次setXXX时状态可复用;
- 注意传入新对象才会触发更新;