如何在setState中使用异步函数并能够撤消到最新状态

时间:2020-07-08 22:22:30

标签: reactjs react-native react-hooks

我需要始终将开关状态从选中状态更改为未选中状态,反之亦然,但是在执行每个操作后,我需要执行请求以使用API​​更新状态,但是如果请求失败,则必须回滚到前一个状态开关值。我已经尝试过在setState内进行操作,并且如果没有多个并行操作并且这些并行操作返回一些错误,则可以正常工作。

我已经尝试过使用useEffect,但是我遇到了产生无限循环的问题,因为激活useEffect的变量也与我需要回滚到最新值的变量相同,因此会产生无限循环。此外,当状态具有初始值([])或第一次对setState的调用来自首次从API提取数据(componentDidMount提取)时,我需要避免调用api。

是否有一个聪明的方法可以做到这一点而又不会在加载屏幕上挡住用户,并且仍然能够始终撤消出错的更改?

这是我期望的图像:

enter image description here

以下是我尝试过并在某些情况下可以使用的代码的一部分:

interface Option {
  key: string
  pushNotificationTypeData: PushNotificationTypeData
  name: string
  checked: boolean
  onValueChange: () => void
}


const CustomizeNotificationsScreen: React.FunctionComponent<BaseNavigationProps> = ({
  navigation,
}) => {
  const [options, setOptions] = React.useState<Option[]>([])

  const handleSwitchChange = (key: string) => {
    setOptions((prev) => {
      const newOptions = cloneDeep(prev)
      const optionToChangeIndex = newOptions.findIndex((e) => e.key === key)
      newOptions[optionToChangeIndex].checked = !newOptions[optionToChangeIndex].checked

      updateNotificationPermissionsService.execute({
        pushInterval: [{
          type: newOptions[optionToChange].pushNotificationTypeData,
          interval: newOptions[optionToChange].checked
            ? PushNotificationIntervalData.EVER
            : PushNotificationIntervalData.NEVER
        }]
      }).catch(() => {
        showErrorMessage()
        setOptions(prev) // Undo to the the latest change
      })
      return newOptions // Update the options state while the request is being made
    })
  }

0 个答案:

没有答案