简体   繁体   English

ReactJS 使用异步 setState 更新状态的最佳方式

[英]ReactJS best way to update the state with asynchronous setState

I started working with reactjs recently and I know setState() is asynchronous, but if I have the following code below:我最近开始使用 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 })
      }
    })
  }

Great, after the first if, we have our state like this:太好了,在第一个 if 之后,我们的状态是这样的:

{
  adrCity: null
  adrCountry: null
  adrStNumber: "65"
  adrState: null
  adrStreet: null
  adrZipcode: null
}

But because setState is asynchronous, the second if, the ...addressState is still with its initial value (adrStNumber from the last iteration is null), so after the iteration the state will look like this:但是因为 setState 是异步的,第二个 if, ...addressState 仍然是它的初始值(上次迭代的 adrStNumber 为空),所以迭代后状态将如下所示:

{
  adrCity: null
  adrCountry: null
  adrStNumber: null
  adrState: "New York"
  adrStreet: null
  adrZipcode: null
}

In this example, everytime there is a if iteration, I need to add something to my state object.在这个例子中,每次有一个 if 迭代时,我都需要向我的状态对象添加一些东西。 What is the best way to implement something like this?实现这样的事情的最佳方法是什么?

You can buld your object inside your function's body and assign it to the state after all if are checked.你可以球泡你的对象你的函数体内,它毕竟分配到状态if被检查。 Something like below:像下面这样:

// 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)
    })

You can try this:你可以试试这个:

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 });
  })
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM