React中如何在两个state变量更新完成后再执行指定函数?
问题根因
- React的状态更新是异步批量执行的,调用
setCoinbasePrices、setBinancePrices后不会立刻修改当前作用域下的state变量,你在fetch结束后直接调用calculateRec拿到的还是初始的空数组,自然会报错。 - 你当前的写法是两个请求串行执行,会浪费不必要的等待时间,优化成并行请求效率更高。
解决方案
提供两种可直接复用的实现方式,按需选择即可:
方案1:直接用接口返回数据计算(推荐,性能更高)
不用等待状态更新,直接用已经拿到的格式化后的数据执行计算逻辑:
const [coinbasePrices, setCoinbasePrices] = useState([]); const [binancePrices, setBinancePrices] = useState([]); const [recommendations, setRecommendations] = useState({}); useEffect(() => { (async () => { try { // 并行发起两个请求,缩短总等待时间 const [coinbaseRes, binanceRes] = await Promise.all([ fetch('http://localhost:8080/prices/coinbase').then(res => res.json()), fetch('http://localhost:8080/prices/binance').then(res => res.json()) ]) // 格式化数据 const formattedCoinbase = reformatPrices(coinbaseRes) const formattedBinance = reformatPrices(binanceRes) // 更新状态 setCoinbasePrices(formattedCoinbase) setBinancePrices(formattedBinance) // 直接用格式化完成的数据计算,不用等状态更新 setRecommendations(calculateRec(formattedCoinbase, formattedBinance)) } catch (err) { throw err } })(); }, []);
方案2:监听状态变化触发计算
如果业务逻辑必须等状态更新完成后再执行,可以单独加一个useEffect监听两个价格状态:
const [coinbasePrices, setCoinbasePrices] = useState([]); const [binancePrices, setBinancePrices] = useState([]); const [recommendations, setRecommendations] = useState({}); // 负责拉取数据更新两个价格状态 useEffect(() => { (async () => { try { const [coinbaseRes, binanceRes] = await Promise.all([ fetch('http://localhost:8080/prices/coinbase').then(res => res.json()), fetch('http://localhost:8080/prices/binance').then(res => res.json()) ]) setCoinbasePrices(reformatPrices(coinbaseRes)) setBinancePrices(reformatPrices(binanceRes)) } catch (err) { throw err } })(); }, []); // 两个价格状态都更新完成后再执行计算 useEffect(() => { // 自定义校验逻辑,避免初始空数组触发报错 if(coinbasePrices.length && binancePrices.length) { setRecommendations(calculateRec(coinbasePrices, binancePrices)) } }, [coinbasePrices, binancePrices])
注意事项
如果reformatPrices处理后可能返回空数组,把上述判断条件替换为你自己的业务校验规则即可,比如判断是否存在某个必填字段。
内容的提问来源于stack exchange,提问作者muth
相关产品推荐
相关产品推荐

