React Native状态变更后组件不重新渲染问题求助
React Native 状态更新后组件未重新渲染问题修复
你的问题核心在于第二个计算AmmountOwe的逻辑——它依赖组件状态username,但状态更新是异步的,且这段逻辑和第一个计算逻辑并行执行,导致它拿到的username还是初始旧值;就算后续setUsername完成,这段逻辑也不会重新触发,组件自然不会更新。
看你的代码:第一个函数通过fetchUsername拿到uname后,一边用setUsername更新状态,一边把uname传给后续计算;但第二个函数直接调用组件的username状态,此时username还没完成更新(React状态更新是异步批量处理的),所以计算结果错误;后续username更新后,这段逻辑也不会自动重新执行,组件因此不会重新渲染。
修复方案
方案1:复用已获取的uname值(推荐)
把第二个计算逻辑整合到第一个函数的Promise链条中,直接用同步拿到的uname,彻底避开状态异步更新的问题:
fetchUsername().then((uname) => { setUsername(uname); // 并行执行两个计算逻辑,统一使用uname而非组件状态 return Promise.all([ // 计算收款金额 fetchPaymentsInChat(props.threadID).then((payments) => { return Promise.all( payments.map(pid => { return fetchPayment(pid).then(paymentDetails => { return paymentDetails.sender === uname ? paymentDetails.value * paymentDetails.users.length : 0; }); }) ); }).then((paymentValues) => { const paymentSum = paymentValues.reduce((acc, val) => parseInt(acc) + parseInt(val), 0); setAmmountReceive(paymentSum); }), // 计算欠款金额,直接使用uname fetchPaymentsInChat(props.threadID).then((payments) => { return Promise.all( payments.map(pid => { return fetchPayment(pid).then(paymentDetails => { return paymentDetails.users.includes(uname) ? paymentDetails.value : 0; }); }) ); }).then((paymentValues) => { const paymentSum = paymentValues.reduce((acc, val) => parseInt(acc) + parseInt(val), 0); setAmmountOwe(paymentSum); }) ]); }).catch(err => { alert(err); });
方案2:用useEffect监听username变化
如果必须依赖组件状态,可将第二个计算逻辑放入useEffect,当username更新时自动触发:
// 组件内部新增useEffect监听 useEffect(() => { if (!username) return; // 避免初始空值触发无效计算 fetchPaymentsInChat(props.threadID).then((payments) => { return Promise.all( payments.map(pid => { return fetchPayment(pid).then(paymentDetails => { return paymentDetails.users.includes(username) ? paymentDetails.value : 0; }); }) ); }).then((paymentValues) => { const paymentSum = paymentValues.reduce((acc, val) => parseInt(acc) + parseInt(val), 0); setAmmountOwe(paymentSum); }).catch(err => { alert(err); }); }, [username, props.threadID]); // 依赖username和threadID,变化时自动执行 // 第一个函数保留,仅负责设置username和计算收款金额 fetchUsername().then((uname) => { setUsername(uname); return uname; }).then((uname) => { return fetchPaymentsInChat(props.threadID).then((payments) => { return Promise.all( payments.map(pid => { return fetchPayment(pid).then(paymentDetails => { return paymentDetails.sender === uname ? paymentDetails.value * paymentDetails.users.length : 0; }); }) ); }).then((paymentValues) => { const paymentSum = paymentValues.reduce((acc, val) => parseInt(acc) + parseInt(val), 0); setAmmountReceive(paymentSum); }); }).catch(err => { alert(err); });
方案1通过同步值规避异步状态的坑,方案2利用useEffect的依赖监听确保状态更新后重新计算,两者都能根治组件不更新的问题。
内容的提问来源于stack exchange,提问作者Adam Bournes
相关产品推荐
相关产品推荐

