使用软件包reactn
当我将these lines (1)替换为those lines (2)时,代码起作用了。 (2)是一种解决方法,处理异步setState,但我想了解为什么(1)不起作用。
据我所知,我可以将回调函数传递给React Hooks中的setSomeState
:
如果新状态是使用先前状态计算的,则可以将函数传递给
setState
This也是reactn
文档中useGlobal
的另一种用法,它还使用回调函数作为setGlobal
的参数。为什么他们的示例有效,而我的无效?
完整代码::https://snack.expo.io/@loia5tqd001/d26e8f
摘要:
listSymbols = [ "USD", "EUR", ... ]
usdRates = {} // expect to be usdRates = { USD: 1, EUR: 0.9 ... }
// getExchangeRate is in utils/utils.js
// => The code doesn't work
for (const symbol of listSymbols) {
getExchangeRate("USD", symbol).then(exchangeRate => {
setUsdRates(oldUsdRates => ({
...oldUsdRates,
[symbol]: exchangeRate
}))
.then(() => console.log("Call api getting exchange rate for " + symbol, usdRates) )
})
}
// => The code works as expected
for (const symbol of listSymbols) {
getExchangeRate("USD", symbol).then(exchangeRate => {
usdRates[symbol] = exchangeRate
console.log("Call api got exchange rate for " + symbol, usdRates)
})
}
setUsdRates(usdRates)
答案 0 :(得分:1)
好的,我会尝试在这里清除一些内容 如你所说
usdRates = {} // expect to be usdRates = { USD: 1, EUR: 0.9 ... }
所以应该是一个对象
const [usdRates, setUsdRates] = useGlobal({})
然后做
useEffect(() => {
for (const symbol of listSymbols) {
getExchangeRate("USD", symbol).then(exchangeRate => {
setUsdRates(oldUsdRates => ({
...oldUsdRates,
[symbol]: exchangeRate
}))
.then(() => console.log("Call api getting exchange rate for " + symbol, usdRates)
)
})
}
}, [])
希望有帮助
答案 1 :(得分:1)
基于reactn的来源,使用钩子的useGlobal('propertyName')
版本时似乎不支持updater函数样式。
这是属性设置器的定义:https://github.com/CharlesStover/reactn/blob/master/src/use-global.ts#L95
您可以看到它创建了一个newGlobalState
对象,并将其传递给setGlobal
。
然后setGlobal
在此处的全局状态管理器上调用set
:https://github.com/CharlesStover/reactn/blob/master/src/global-state-manager.ts#L302
由于属性设置程序中的newGlobalState
始终是对象,因此永远不会使用更新程序版本。
您可以通过不传递任何内容到useGlobal
并处理整个状态对象来实现所需的目标,如您链接的文档中的示例所示:
const [global, setGlobal] = useGlobal();
...
getExchangeRate("USD", symbol).then(exchangeRate => {
setGlobal(oldGlobal => ({
...oldGlobal,
usdRates: {
...oldGlobal.usdRates,
[symbol]: exchangeRate,
},
}))
.then(() => console.log("Call api getting exchange rate for " + symbol, usdRates) )
})
}
我也不确定您的其他示例是否100%正确-在所有异步setUsdRates
调用完成之前,您不会等待调用getExchangeRate
。