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

时间:2019-12-24 19:04:04

标签: javascript reactjs

我最近开始使用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迭代时,我都需要向状态对象中添加一些内容。实现这样的最佳方法是什么?

2 个答案:

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