hooks出来很久了,最近才开始使用。好用,但是,作为个新手还是遇到了一些问题,几乎都是一些低级问题。总结一下,加深记忆。
useCallback
- 依赖项变了,但内部没有取到最新的值
- 背景:接入页面时,接口获取orderBaseInfo,点击元素执行goPoiSerch方法,此方法内部调用handlSearch。在handlSearch中,输出的orderBaseInfo却是旧的值。代码如下:
const goPoiSerch = useCallback(() => {
...
handleSearch(xx)
}, [])
...
const handlSearch = useCallback((xx) => {
console.log(orderBaseInfo);
}, [orderBaseInfo])
- 尝试查看orderBaseInfo取值是否正确,是否进行更新
const usePrevious = (value) => {
const ref = useRef()
useEffect(() => {
ref.current = value
}, [value])
return ref.current
}
const prevOrderInfo = usePrevious(orderBaseInfo)
if (prevOrderInfo !== orderBaseInfo) {
console.warn('no equal >>', prevOrderInfo, orderBaseInfo);
}
输出结果取值正确,且发生了变化的。
- 确认问题是依赖项引起的 在goPoiSerch方法中执行handlSearch,但没有将handelSearch作为依赖项,导致的无法正常取值。 在这一步停留的时间最长。一直都在查看handlSearch的依赖项是否正确,不断的尝试,又不断的否定判断。究其原因,是对hooks原理的不熟悉,不明白hooks中的方法在必要时候也应该作为依赖项。
- 使用 useCallback 来缓存函数,不过需要注意的是,useCallback 通过闭包获得 state,因此 useCallback 的第二个参数需要指定 state。如果 state 频繁变化,如 input 的值,那么 useCallback 的引用无法被缓存,也就失去了缓存的意义。推荐用法:
function Form() {
const [text, updateText] = useState('');
const textRef = useRef();
useEffect(() => {
textRef.current = text; // textRef 每次渲染不会发生变化
});
//不推荐text为依赖项
// const handleSubmit = useCallback(() => {
// console.log(text);
// }, [text]); // input 的值,经常变化
//推荐textRef为依赖项
const handleSubmit = useCallback(() => {
const currentText = textRef.current; // 从 textRef 中读取 text
alert(currentText);
}, [textRef]); // useCallback 的第二个参数设置为 textRef
return (
<>
<input value={text} onChange={e => updateText(e.target.value)} />
<ExpensiveTree onSubmit={handleSubmit} /> // onSubmit 被缓存
</>
);
}
。。。待补充