https://segmentfault.com/a/1190000020108840
死循环
01: Child使用useEffect获取数据,对getData有依赖,于是将其加入依赖列表
02: getData执行时,调用setVal,导致App重新渲染
03: App重新渲染时生成新的getData方法,传给Child
function FatherTest() {
const [val, setVal] = useState("");
function getData() {
setTimeout(() => {
setVal("new data " + count);
count++;
}, 500);
}
return <Child val={val} getData={getData} />;
}
function Child({ val, getData }) {
useEffect(() => {
getData();
}, [getData]);
return <div>{val}</div>;
}
解决死循环
function FatherTest() {
const [val, setVal] = useState("");
// 01: getData改变的时候,是需要重新获取数据的。这时就需要通过useCallback来将引用固定住
const getData = useCallback(() => {
setTimeout(() => {
setVal("new data " + count);
count++;
}, 500);
}, []);
return <Child val={val} getData={getData} />;
}
解决死循环:问题 =》 如果 useCallback需要依赖val,则再次进入死循环 =》 自定义hook
// 自定义hook
function useRefCallback(fn, dependencies) {
const ref = useRef(fn);
// 每次调用的时候,fn 都是一个全新的函数,函数中的变量有自己的作用域
// 当依赖改变的时候,传入的 fn 中的依赖值也会更新,这时更新 ref 的指向为新传入的 fn
useEffect(() => {
ref.current = fn;
}, [fn, ...dependencies]);
return useCallback(() => {
const fn = ref.current;
return fn();
}, [ref]);
}
// 调用
const getData = useRefCallback(() => {
setTimeout(() => {
setVal("new data " + count);
count++;
}, 500);
}, [val]);