关于usecallback的坑

看下下面这段代码,点击后会打印什么内容

const Mytest = () => {
  const [state, setState] = useState({
    a: 1
  })
  useEffect(() => {
    setState({
      a: 4
    })
  }, []);
  
  const handleClick = useCallback(() => {
    console.log(state)
  }, [ ]);
  
  return (
    <div onClick={handleClick}>
      click me
    </div>)
};
export default Mytest;

触发handleClick,打印出来的值为:
{ a: 1 }

为什么呢?
明明useEffect发生在组件挂载完了之后才执行的,触发handleClick的时候,按理说state已经更新了,
但为什么还是拿到了没有更新之前的值呢?
原因就出在useCallback, useback对函数做了一次缓存,如果它的依赖是个空数组,就只会在第一次渲染的时候生成一个handleClick函数引用,后面的每次都渲染都复用之前的函数,并且用useCallback包住的函数,已经形成了一个闭包,闭包内用了外部的变量, 在函数执行完后,并没有销毁这个变量, 所以再次调用这个函数的时候, 还是用的之前的变量

如果把函数handleClick改成如下,以来

  const handleClick = useCallback(() => {
    console.log(state)
  }, [state ]);

{ a: 4 }
这时候,state有更新的时候,就会重新执行这个useCallback, 返回一个新的函数引用, 这样就能拿到最新的state了

function Parent(){
	const [query,setQuery] = useState('q');
  const fetchData = useCallback(()=>{
  	...省略函数体的具体实现
  },[query]);
  return <Child fetchData={fetchData} />
}
  
function Child({fetchData}){
  const [data,setData] = useState(null);
	useEffect(()=>{
  	fetchData().then(setData);
  },[fetchData])

经过 useCallback 包装过的函数可以当作普通变量作为 useEffect 的依赖。 useCallback做的事情,就是在其依赖变化时,返回一个新的函数引用,触发 useEffect 的依赖变化,并激活其重新执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值