使用async setState

时间:2017-04-12 12:55:19

标签: reactjs react-jsx jsx

我有调度动作的功能。我想在动作之前和之后显示一个加载器。我知道组成传递给setState的对象的反应。问题是如何以异步方式更新属性:

handleChange(input) {
    this.setState({ load: true })
    this.props.actions.getItemsFromThirtParty(input)
    this.setState({ load: false })
}

基本上,如果我将此属性作为应用程序状态的一部分(使用Redux),这一切都很有效,但我真的更喜欢将此属性仅用于组​​件状态。

6 个答案:

答案 0 :(得分:37)

你可以将setState包装在Promise中并使用async / await,如下所示

setStateAsync(state) {
    return new Promise((resolve) => {
      this.setState(state, resolve)
    });
}

async handleChange(input) {
    await this.setStateAsync({ load: true });
    this.props.actions.getItemsFromThirtParty(input);
    await this.setStateAsync({ load: false })
}

来源:ASYNC AWAIT With REACT

答案 1 :(得分:21)

将其余代码包装在第一个setState

的回调中
handleChange(input) {
  this.setState({
    load: true
  }, () => {
    this.props.actions.getItemsFromThirtParty(input)
    this.setState({ load: false })
  })
}

这样,您的load保证在调用true之前设置为getItemsFromThirtPartyload设置回false

这假设您的getItemsFromThirtParty函数是同步的。如果不是,请将其转换为承诺,然后在链式setState方法中调用最终then()

handleChange(input) {
  this.setState({
    load: true
  }, () => {
    this.props.actions.getItemsFromThirtParty(input)
      .then(() => {
        this.setState({ load: false })
      })
  })
}

答案 2 :(得分:1)

这是你可以做的......

  1. 更改您的操作以接受onFetchComplete回调以及input
  2. 将handleChange更改为 -

    handleChange(input) {
        this.setState({ load: true }, ()=>
            this.props.actions.getItemsFromThirtParty(input,
            ()=>this.setState({ load: false }))
        );
    }
    
  3. 这将确保动作处理器代码可以调用状态更改回调,即使它不是以基于承诺的方式编写的。

答案 3 :(得分:1)

这是“ async-await” setState的打字稿实现:

async function setStateAsync<P, S, K extends keyof S>(
  component: Component<P, S>,
  state:
    ((prevState: Readonly<S>, props: Readonly<P>) => (Pick<S, K> | S | null)) |
    Pick<S, K> |
    S |
    null
) {
  return new Promise(resolve => component.setState(state, resolve));
}

答案 4 :(得分:0)

使用promise for action creators和async / await的小更新效果很好,与“then”链接相比,它使代码更加清晰:

(async () => {
   try {
    await this.props.actions.async1(this.state.data1);
    await this.props.actions.async2(this.state.data2) 
    this.setState({ load: false );
   } catch (e) {
    this.setState({load: false, notify: "error"});
   }
})();

当然这是一个品味问题。

编辑:添加了缺失的括号

答案 5 :(得分:0)

之前的答案不适用于 Hooks。在这种情况下,将第二个参数传递给 setState

时会出现以下错误 <块引用>

警告:来自 useState() 和 useReducer() 钩子的状态更新不支持第二个回调参数。要在渲染后执行副作用,请在组件主体中使用 useEffect() 声明它。

如错误消息所述,在这种情况下,您需要使用 useEffect(另请参阅 this discussion 以获取更多详细信息)