React课程导航组件需双击才能正确获取点击索引问题求助
React导航组件点击课时项需双击触发正确操作的问题解决
问题原因
React的状态更新是异步批量执行的。你在点击事件里先调用setClicked(index),紧接着就执行handleOtp()——这时候clicked状态还没完成更新,handleOtp里拿到的还是旧的索引值。第二次点击时,clicked已经更新为上一次的索引,才能拿到正确值,所以出现了双击才生效的情况。
解决方案
方案1:直接将index传入handleOtp(推荐)
修改handleOtp函数,让它接收index参数,不再依赖组件状态clicked,这样能直接拿到当前点击的正确索引:
// 修改后的handleOtp函数 const handleOtp = async (index) => { try { // 直接用传入的index获取lessonId,跳过状态依赖 const lessonId = course.lessons[index]?.video?.id; const { data } = await axios.post("/api/videoOtp", { videoId: lessonId, username: user.username, ip, }); if (!data.otp && !data.playbackInfo) { return toast.error("Video OTP Failed! Reload Page"); } loadVideo({ otp: data.otp, playbackInfo: data.playbackInfo, configuration: { autoplay: true, }, container: container.current, }); } catch (err) { console.error(err); } };
然后修改点击事件的调用:
<Item onClick={async () => { setClicked(index); setIsLoading(true); setSpin(true); setCheckoutVisibility("none"); checkTransactionStatus(index); setPaymentMethod("kiosk"); setKioskPhoneNumber(""); // 直接把当前index传给handleOtp handleOtp(index); }} key={index} icon={<Avatar>{index + 1}</Avatar>} >
方案2:用useEffect监听clicked状态变化
如果必须依赖clicked状态,可以添加一个useEffect,当clicked更新后自动执行handleOtp:
import { useEffect } from 'react'; // 监听clicked变化,状态更新后执行handleOtp useEffect(() => { // 可以加个判断,比如只有clicked是有效索引时才执行 if (clicked !== undefined && course.lessons[clicked]) { handleOtp(); } }, [clicked, course.lessons]); // 依赖项包含clicked和course.lessons,避免闭包过期
然后点击事件里去掉handleOtp()的调用:
<Item onClick={async () => { setClicked(index); setIsLoading(true); setSpin(true); setCheckoutVisibility("none"); checkTransactionStatus(index); setPaymentMethod("kiosk"); setKioskPhoneNumber(""); // 不再在这里调用handleOtp,交给useEffect处理 }} key={index} icon={<Avatar>{index + 1}</Avatar>} >
内容的提问来源于stack exchange,提问作者Ahmed Mostafa
相关产品推荐
相关产品推荐

