我有一个正在运行的应用程序,我正在尝试将状态设置为loading: true
,同时我的应用程序进行提交调用,以便我可以显示加载屏幕。因为我想确保在进行加载调用之前设置状态,所以我使用了回调。但是,我没有看到我的加载更新与下面的代码:
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 });
};
当我检查我的控制台日志时,我发现状态没有更新,加载仍然是假的。
我在这里缺少什么?
答案 0 :(得分:3)
这种情况正在发生,因为您在功能结束时正在调用this.setState({ loading: false });
。
您正在同时设置loading: true
和loading: false
。当您的回调正在调用时,最后一个setState函数也将状态值更改为false。
收到请求后,您应该将加载状态设置为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);
}
});
};
答案 1 :(得分:2)
这是因为您在异步操作完成之前将loading
设置为false
只需在this.setState({ loading: false });
;
callback
即可
修改强>
作为评论的后续内容:
我尝试删除它但看到了相同的结果
我没有说要在setstate
的回调中将移动删除它。
发生的情况是,您在相同的调用堆栈迭代中将其设置为true
然后false
,而不是等待异步操作完成。
请考虑与您的代码类似的场景:
在此示例中,我在异步操作(loading
)完成之前将setTimeout
设置为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'
});
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>