React中如何在状态更新完成后执行依赖函数?
问题解决方案
核心问题分析
你遇到的问题本质是React的setState是异步操作,await setIndividualDetails()根本等不到individualData状态更新完成。而且你原来的逻辑里,在certificateData加载完成后直接发起请求,但此时individualData还没完成更新,自然拿不到transaction_hash。
正确的实现方式
我们可以把逻辑拆成两步,确保只有当individualData确实拿到有效数据后,才执行API请求:
- 当
certificateData或params.QRurl变化时,更新individualData - 当
individualData存在且包含transaction_hash时,执行axios请求
修改后的完整代码如下:
export function Details() { const params = useParams(); const certificateData = useContext(DataContext); const [individualData, setIndividualData] = useState(null); // 初始设为null更合理,因为目标是单个对象而非数组 const [tokenID, setTokenID] = useState(''); // 同步更新individualData,无需async const setIndividualDetails = () => { const foundData = certificateData.find(uploadedFile => uploadedFile.QRurl === params.QRurl); setIndividualData(foundData); }; // 单独封装API请求逻辑 const fetchTokenID = async () => { try { const { data } = await axios({ method: "GET", url: `https://api.nftport.xyz/v0/mints/${individualData.transaction_hash}?chain=polygon`, headers: { 'Content-Type': 'application/json', Authorization: '4d86xxxxxx-929e-xxxx' } }); setTokenID(data.token_id); console.log(data.token_id); } catch (error) { console.log(error); } }; // 第一个useEffect:负责更新individualData useEffect(() => { if (!certificateData || certificateData.length === 0) return; setIndividualDetails(); }, [certificateData, params.QRurl]); // 加上params.QRurl依赖,防止URL参数变化时不更新数据 // 第二个useEffect:仅在individualData有效时执行请求 useEffect(() => { if (!individualData || !individualData.transaction_hash) return; fetchTokenID(); }, [individualData]); // 依赖individualData,状态更新后自动触发请求 return ( <div> {individualData?.transaction_hash && <h2>{individualData.transaction_hash}</h2>} </div> ); }
为什么你的修改没生效?
你修改后的useEffect里,调用setIndividualDetails()后立刻判断individualData,但此时setState还没完成,individualData还是旧值,所以这个判断永远会提前返回,不会执行fetchTokenID。必须等组件重新渲染、individualData更新后,再通过依赖触发新的useEffect执行请求。
额外优化点
- 把
individualData初始值从[]改为null,符合单个对象的语义,判断逻辑更清晰 - 在return里用可选链
?.简化空值判断 - 给第一个useEffect加上
params.QRurl依赖,避免URL参数变化时数据不更新
内容的提问来源于stack exchange,提问作者rohit
相关产品推荐
相关产品推荐

