hooks使用小总结

120 阅读1分钟

hooks出来很久了,最近才开始使用。好用,但是,作为个新手还是遇到了一些问题,几乎都是一些低级问题。总结一下,加深记忆。

useCallback

  1. 依赖项变了,但内部没有取到最新的值
  • 背景:接入页面时,接口获取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 被缓存
    </>
  );
}

。。。待补充