javascript - 等待异步数据以状态存储在 React 或 React Native 中的正确方法

标签 javascript reactjs react-native

我需要从我的 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 个这样的数据库查询,并且需要知道在渲染组件之前我已经返回数据。

谢谢!

最佳答案

使用componentDidMount 生命周期 Hook 在组件初始化时获取异步数据。这应该在使用异步获取的数据的组件中完成,或者在多个组件使用的数据的最近共同祖先中完成。这样做的原因是为了减少异步检索完成后重新呈现的组件的数量。

Keep in mind you will also need to account for a loading state, before your async data is available.

下面是这些原则的一个基本示例。

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 调用的 then 方法中的 setState 进行异步调用和更新状态。如果您将方法用作事件处理程序,请确保将方法的 this 上下文绑定(bind)到构造函数中。

希望这对您有所帮助。如果您有任何问题,请提出!

关于javascript - 等待异步数据以状态存储在 React 或 React Native 中的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45339799/

相关文章:

javascript - React 不渲染第二个嵌套元素

javascript - Angularjs 没有为 Bootstrap Popover 插入标题

javascript - jQuery 手机 : refresh after dynamically adding rows to a table with column toggle

reactjs - 使用递归函数创建嵌套元素

firebase - 使用 putString 调用 React-native Firebase 存储上传

react-native - 如何使用 react native 底部选项卡将顶部边框添加到事件选项卡

react-native - 打开/关闭抽屉导航在 native react 中不起作用

javascript排除 "00"和 "01"字符串

reactjs - NextJS/Typescript/Apollo 错误;属性在类型上不存在

javascript - 使用 socket.io 事件更新状态