我最近开始使用reactjs,我知道setState()是异步的,但是如果下面有以下代码:
// the state is an object
const [addressState, setAddress] = useState({
adrStNumber: null,
adrStreet: null,
adrCity: null,
adrState: null,
adrZipcode: null,
adrCountry: null
})
// this function is called when I select an option in the input
function getAddressAndSaveToState(address) {
address.map(adr => {
if (adr.types.includes('street_number')) {
const adrStNumber = adr.long_name
setAddress({ ...addressState, adrStNumber: adrStNumber })
}
if (adr.types.includes('route')) {
const adrStreet = adr.long_name
setAddress({ ...addressState, adrStreet: adrStreet })
}
if (adr.types.includes('administrative_area_level_1')) {
const adrState = adr.long_name
setAddress({ ...addressState, adrState: adrState })
}
})
}
太好了,在第一个条件之后,我们的状态如下:
{
adrCity: null
adrCountry: null
adrStNumber: "65"
adrState: null
adrStreet: null
adrZipcode: null
}
但是因为setState是异步的,所以第二个if,... addressState仍然具有其初始值(上次迭代的adrStNumber为null),因此在迭代之后,状态将如下所示:
{
adrCity: null
adrCountry: null
adrStNumber: null
adrState: "New York"
adrStreet: null
adrZipcode: null
}
在此示例中,每当有一个if迭代时,我都需要向状态对象中添加一些内容。实现这样的最佳方法是什么?
答案 0 :(得分:2)
可以在所有函数if
被检查之后将对象放置在函数体内,并将其分配给状态。如下所示:
// this function is called when I select an option in the input
function getAddressAndSaveToState(address) {
address.map(adr => {
let newAddress = {...addressState}
if (adr.types.includes('street_number')) {
const adrStNumber = adr.long_name
newAddress.adrStNumber = adrStNumber
}
if (adr.types.includes('route')) {
const adrStreet = adr.long_name
newAddress.adrStreet = adrStreet
}
if (adr.types.includes('administrative_area_level_1')) {
const adrState = adr.long_name
newAddress.adrState = adrState
}
setAddresss(newAddress)
})
答案 1 :(得分:1)
您可以尝试以下方法:
function getAddressAndSaveToState(address) {
address.map(adr => {
const newAddressState = {};
if (adr.types.includes('street_number')) {
const adrStNumber = adr.long_name
newAddressState.adrStNumber = adrStNumber;
}
if (adr.types.includes('route')) {
const adrStreet = adr.long_name
newAddressState.adrStreet = adrStreet;
}
if (adr.types.includes('administrative_area_level_1')) {
const adrState = adr.long_name
newAddressState.adrState = adrState;
}
setAddress({ ...addressState, ...newAddressState });
})
}