最近在项目中遇到一个棘手的问题,使用useState获取到的一直是初始值;下面用一个例子来说明问题的产生和解决的方案
import React, { useState, useEffect, useRef, useCallback } from "react";
import { useEventListener, useMemoizedFn } from "ahooks";
export default () => {
const [value, setValue] = useState(0);
const ref = useRef(null);
const getValue2 = () => {
// 获取不到外部的数据 一直为初始值
console.log("getValue2", value);
};
const getValue = () => {
// 获取不到外部的数据 一直为初始值
console.log("getValue", value);
getValue2();
};
useEffect(() => {
document.addEventListener("scroll", getValue);
return () => {
document.removeEventListener("scroll", getValue);
};
}, []);
useEventListener(
"click",
() => {
setValue((v) => v + 1);
},
{ target: ref }
);
return (
<div style={{ height: 1000 }}>
<button ref={ref} type="button">
You click {value} times
</button>
</div>
);
};
简单描述下:使用useEffect来监听scroll触发事件,打印点击的次数,会发现两次的打印都为初始值:0;即如果用useEffect来监听事件,其中依赖为空,会导致监听事件里的回调获取不到外部的数据;
解决方案
方案一:通过useRef做一层转换
const getValue = () => {
console.log("getValue", value);
getValue2();
};
const ref 2= useRef(getValue)
ref2.current = getValue
useEffect(() => {
const getValueNew= () => ref2.current()
document.addEventListener("scroll", getValueNew);
return () => {
document.removeEventListener("scroll", getValueNew);
};
}, []);
方案二:使用ahooks的useMemoizedFn
const getValue = useMemoizedFn(() => {
console.log("getValue", value);
getValue2();
});