我需要从我的SQLite数据库中获取数据,然后将其保存在我的组件状态中。数据库部分工作正常,问题是它没有足够快地保存到状态。如果我用setTimeout添加一些人工延迟,那么它工作正常。我怎样才能更好地将这些东西捆绑在一起,这样才能在没有百万次回调的情况下以正确的顺序和时间运行?
这不起作用:
let returnedData;
// This function works, the data comes back correctly eventually
returnedData = getDataFromDB();
this.setState({
dbData: returnedData //but returnedData is still empty at this point
})
// Data is not back in time to see in the variable or in state:
console.log(returnedData); // Undefined
console.log(this.state.dbData); // Undefined
但这确实有效:
let returnedData;
returnedData = getDataFromDB();
// If I add this tiny delay, it all works
setTimeout(function(){
this.setState({
dbData: returnedData
})
console.log(returnedData); // Shows correct data
console.log(this.state.dbData); // Shows correct data
},100);
我想尝试找到一种方法,让它在没有人工延迟的情况下工作。当我的组件正在加载时,我将需要在componentWillMount中执行大约3个这样的数据库查询,并且在呈现组件之前需要知道我有数据。
谢谢!
答案 0 :(得分:1)
使用componentDidMount
生命周期钩子在初始化组件时获取异步数据。这应该在使用异步获取的数据的组件中完成,或者在多个组件使用的数据的最近共同祖先中完成。这样做的原因是在异步检索完成后减少重新渲染的组件的数量。
请注意,在您的异步数据可用之前,您还需要考虑 loading 状态。
以下是原则的基本示例。
class ComponentThatRequiresAsyncData extends PureComponent {
constructor( props ) {
super( props );
// initialize state
this.state = {
data: null
}
}
// handle async operation in this lifecycle method to ensure
// component has mounted properly
componentDidMount() {
axios.get( "some_url" )
.then( ( response ) => {
// once you have your data use setState to udpate state
this.setState( ( prevState, props ) => {
return { data: response.data };
})
})
.catch( ( error ) => {
// handle errors
});
}
render() {
const { data } = this.state;
return (
{
data ?
<WhatEverIWantToDoWithData data={ data } /> :
<p>Loading...</p>
}
);
}
}
对于因事件而需要加载的数据使用相同的想法,例如单击按钮。您可以使用componentDidMount
制作自己的方法,在http调用的setState
方法中通过then
进行异步调用和更新状态。如果您将它用作事件处理程序,请确保在构造函数中绑定方法的this
上下文。
希望这会有所帮助。如果您有任何疑问,请询问!