采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
老师请问useCallback可以像useMemo的第二个参数写条件表达式吗 试了一下为什么只有第一次有效果加一了, 还有个疑问就是useCallback如果不可以写条件判断的话,只能写依赖的状态,第一次渲染的时候这个函数可以执行,当clickCount改变的时候这个函数可可以执行,这么理解对吗?感觉有点绕,那useMemo第二个参数满足条件的时候才可以执行,那为什么从第一次不满足条件的时候还可以执行呢
你好同学,useMemo/useCallback/useEffect第二个参数是一致的,都可以传入任意复杂度的同步计算表达式。
根据你的描述,我推测出下面的代码:
function
App() {
const [clickCount, setClickCount] = useState(0);
const handleClick = useCallback(() => {
setClickCount(clickCount + 1);
}, [clickCount === 2]);
return
(
<div>
<button onClick={handleClick}>Press</button>
<span>{clickCount}</span>
</div>
)
}
export
default
App;
多次点击按钮,显示的clickCount一直是1,这是正确的。
这是因为,clickCount === 2这个表达式的值没变,造成了handleClick没变,同时里面引用的上下文也没变,clickCount一直停留在0的状态,即使加1,最多也就变成1,并不会再变了。
具体是这样的过程:
首次渲染,handleClick所指向的这个函数,它读取到的上下文是 {clickCount: 0};
点击按钮,调用 setClickCount,clickCount变成1,触发第二次渲染;
第二次渲染,计算useCallback的第二个参数,发现依然是false,那么useCallback依然会返回之前的函数给 handleClick,handleClick内部能读取到的 clickCount 依然是0;
再次点击按钮,调用handleClick,setClickCount还是只能传入 0+1,还是1,React发现数据相同,不会触发重新渲染;
一直保持这个状态
之所以出现这个问题是你实际上引入了一个闭包,也就是handleClick引用了外部上下文的数据,而作为函数组件,每次重新渲染,都会创建一个新的上下文,而handleClick句柄指向的还是旧上下文。
解决这个问题很简单,就是传入函数给 setClickCount:
setClickCount(count => count + 1)
这样并没有引用任何上下文的数据,因此是安全的。当然把useCallback的第二个参数改成 [clickCount] 或者不加第二个参数也能解决问题。
作为第二个依赖参数,没有满足与不满足的说法,只有变化与未变化,只有变化了才会重新执行,第一次渲染的时候,无从对比,都会先执行一次,不论useMemo/useCallback还是useEffect。
祝您学习愉快!
非常感谢!谢谢老师及时回答问题
这个老师不用回答啦,上个问题已经帮我解决了,感谢老师
登录后可查看更多问答,登录/注册
"快手"大神教你制作堪比原生APP体验的PWA应用,进阶高级开发
1.1k 8
1.3k 7
1.5k 7
1.3k 6
1.2k 5
购课补贴联系客服咨询优惠详情
慕课网APP您的移动学习伙伴
扫描二维码关注慕课网微信公众号