我有调度动作的功能。我想在动作之前和之后显示一个加载器。我知道组成传递给setState
的对象的反应。问题是如何以异步方式更新属性:
handleChange(input) {
this.setState({ load: true })
this.props.actions.getItemsFromThirtParty(input)
this.setState({ load: false })
}
基本上,如果我将此属性作为应用程序状态的一部分(使用Redux),这一切都很有效,但我真的更喜欢将此属性仅用于组件状态。
答案 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 })
}
答案 1 :(得分:21)
将其余代码包装在第一个setState
:
handleChange(input) {
this.setState({
load: true
}, () => {
this.props.actions.getItemsFromThirtParty(input)
this.setState({ load: false })
})
}
这样,您的load
保证在调用true
之前设置为getItemsFromThirtParty
,load
设置回false
。
这假设您的getItemsFromThirtParty
函数是同步的。如果不是,请将其转换为承诺,然后在链式setState
方法中调用最终then()
:
handleChange(input) {
this.setState({
load: true
}, () => {
this.props.actions.getItemsFromThirtParty(input)
.then(() => {
this.setState({ load: false })
})
})
}
答案 2 :(得分:1)
这是你可以做的......
onFetchComplete
回调以及input
。将handleChange更改为 -
handleChange(input) {
this.setState({ load: true }, ()=>
this.props.actions.getItemsFromThirtParty(input,
()=>this.setState({ load: false }))
);
}
这将确保动作处理器代码可以调用状态更改回调,即使它不是以基于承诺的方式编写的。
答案 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 以获取更多详细信息)