我在使用软件包时遇到setState问题:reactn
当我将这些行 (1( 替换为这些行 (2( 时,代码有效。(2( 是一种解决方法,处理异步 setState,但我想了解为什么 (1( 不起作用。
据我所知,我可以在 React Hooks 中将一个回调函数传递给setSomeState
:
如果使用以前的状态计算新状态,则可以将函数传递给
setState
这也是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)
根据 reactn 的来源,使用useGlobal('propertyName')
版本的钩子时似乎不支持更新程序函数样式。
下面是属性设置器的定义: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% 正确 - 您不会等到所有异步getExchangeRate
调用完成时才调用setUsdRates
。
好的,我将尝试在这里清除一些内容 正如你所说
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)
)
})
}
}, [])
希望对你有帮助