setState回调不按预期工作
我有一个工作的应用程序,我只是试图设置状态为loading: true
,而我的应用程序进行提交调用,所以我可以显示加载屏幕。因为我想确保在之前设置状态进行加载调用,所以我使用回调。但是我没有看到我的加载更新代码如下:setState回调不按预期工作
submitSecurityAnswer =() => {
const { submit, handleError, navigate } = this.props;
const { answer } = this.state;
this.setState({ loading: true },() => {
console.log('setState', this.state)
try {
submit({ answer, ...this.props }).then(({ errors, status }) => {
this.setState({ answer: '' });
if (status && status === 200) {
navigate();
} else if (status === 401) {
this.setState({ showError: true });
} else {
handleError(errors[0]);
}
});
} catch (err) {
console.log(err);
}
});
this.setState({ loading: false });
};
当我检查我的控制台日志我看到,国家还没有更新,加载仍然是假的。
我在这里错过了什么?
发生这种情况,因为你在你的函数结束通话this.setState({ loading: false });
。您可以同时设置loading: true
和loading: false
。当你的回调正在调用时,最后一个setState函数也会将状态值更改为false。
您应该设置负载状态虚假收到请求后:
submitSecurityAnswer =() => {
const { submit, handleError, navigate } = this.props;
const { answer } = this.state;
this.setState({ loading: true },() => {
console.log('setState', this.state)
try {
submit({ answer, ...this.props }).then(({ errors, status }) => {
this.setState({ answer: '' });
if (status && status === 200) {
navigate();
} else if (status === 401) {
this.setState({ showError: true, loading: false });
} else {
handleError(errors[0]);
}
});
} catch (err) {
console.log(err);
}
});
};
这是因为您在异步操作完成之前将loading
设置为false
。
只需在callback
内移动this.setState({ loading: false });
;
编辑
作为随访到您的评论:
我试图消除这一点,但看到了同样的结果
我没说要删除它只是移动它内部回调setstate
。
发生了什么是您将它设置为true
,然后false
在相同的调用堆栈迭代,而不是等待异步操作完成。
考虑这个情景,这是类似代码:
在这个例子中我设置loading
回假异步操作(setTimeout
)之前完成,因此我只是覆盖了以前的状态,而无需等待。
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: false,
message: ''
};
}
componentDidMount() {
this.setState({ loading: true },() => {
console.log(this.state);
setTimeout(() => {
this.setState({
message: 'we have data'
});
console.log(this.state);
}, 500);
});
this.setState({ loading: false });
}
render() {
const {message, loading} = this.state;
return (
<div>
{loading ? <div>Loading...</div> : <div>{message}</div>}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
的修复将是移动回调内的下一个状态改变:
在这个例子中我移动回调内的线this.setState({ loading: false });
异步操作已经完成并且该固定不需要的行为之后。
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: false,
message: ''
};
}
componentDidMount() {
this.setState({ loading: true },() => {
console.log(this.state);
setTimeout(() => {
this.setState({
message: 'we have data'
});
this.setState({ loading: false });
}, 500);
});
}
render() {
const {message, loading} = this.state;
return (
<div>
{loading ? <div>loading...</div> : <div>{message}</div>}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
我试图删除,但看到了相同的结果。 – Turnipdabeets
我没有说删除,我说移动它的回调函数内。看我的例子 –
如果我明白你正在尝试做正确的'this.setState({装:假})'应该是正确的或之前'navigate();' – bennygenel
'后面实际上如果你改变'this.setState({answer:''});'到'this。setState({answer:'',loading:false});'它应该也工作 – bennygenel
是啊,我试图'this.setState({loading:false})''submit()' – Turnipdabeets