React-native阻止函数异步执行?

时间:2016-05-14 22:43:35

标签: ios reactjs firebase react-native firebase-realtime-database

单击我的react Native应用程序中的按钮后,我调用两个函数:getSolutionListFromDatabase,它设置组件的状态以包含此解决方案列表,然后updateDatabaseSolutionList,它添加一个元素此列表并将其推送回Firebase。但是,尽管在第一个函数中正在更新应用程序的状态,但在第二个函数中,状态被记录为未定义,并且在第一个函数中的某些语句之前调用了该函数的日志语句。这些函数是出于某种原因而异步运行的,这是React native的一个特性吗?如果是这样,如何在设置状态之前阻止第二个函数执行?感谢。

onSubmitPressed: function() {
    if (this.checkSolution) {
        this.getSolutionListFromDatabase();
        this.updateDatabaseSolutionList();
        Alert.alert(
            'Correct!',
            "Woohoo!"
        );
    }
},

getSolutionListFromDatabase: function() {
    var thisItemRef = itemsListRef.child(this.state.itemID);
    thisItemRef.once('value', (snap) => {
        var solutionList = snap.val();
        this.setState({
            solutionList: solutionList
        });
        console.log('solution is set as' + this.state.solutionList);
    });
},

updateDatabaseSolutionList: function() {
    var newSolutionList = [];
    console.log('solutionList undefined here' + this.state.solutionList);

    if (this.state.solutionList) {
        newSolutionList = this.state.solutionList;
        newSolutionList.push(this.props.itemID);
    }

    //then push new list to Firebase
},

2 个答案:

答案 0 :(得分:5)

逻辑将始终与answer to your previous question中的逻辑相同。如果事件之间存在依赖关系,则应将调用移至第一个回调:

plt.plot([1,2], lw=4, c='#8f9805')

如果您将先决条件(即onSubmitPressed: function() { if (this.checkSolution) { this.getSolutionListFromDatabase(); } }, getSolutionListFromDatabase: function() { var thisItemRef = itemsListRef.child(this.state.itemID); thisItemRef.once('value', (snap) => { var solutionList = snap.val(); this.setState({ solutionList: solutionList }); console.log('solution is set as' + this.state.solutionList); this.updateDatabaseSolutionList(); }); }, updateDatabaseSolutionList: function() { var newSolutionList = []; console.log('solutionList undefined here' + this.state.solutionList); if (this.state.solutionList) { newSolutionList = this.state.solutionList; newSolutionList.push(this.props.itemID); } Alert.alert( 'Correct!', "Woohoo!" ); //then push new list to Firebase }, )传递给需要它的函数,而不是使用字段/属性,那么这种类型的流程将更容易为您自己遵循:

solutionList

但更好的方法就是将onSubmitPressed: function() { if (this.checkSolution) { this.getSolutionListFromDatabase(); } }, getSolutionListFromDatabase: function() { var thisItemRef = itemsListRef.child(this.state.itemID); thisItemRef.once('value', (snap) => { var solutionList = snap.val(); this.updateDatabaseSolutionList(solutionList); }); }, updateDatabaseSolutionList: function(solutionList) { solutionList.push(this.props.itemID); Alert.alert( 'Correct!', "Woohoo!" ); //then push new list to Firebase }, 新价值直接送到Firebase,而不是首先下载整个数组,然后再添加一个新项目将其发回:

push()

答案 1 :(得分:2)

setState不保证是同步的,因此您不能立即依赖于正在更新的状态。

请参阅https://facebook.github.io/react/docs/component-api.html

  

setState()不会立即改变this.state,但会创建挂起状态转换。在调用此方法后访问this.state可能会返回现有值。

     

无法保证对setState的调用进行同步操作,并且可以对调用进行批处理以获得性能提升。

API确实提供了实际更新状态的回调:

void setState(
  function|object nextState,
  [function callback]
)

或者,您可以将solutionList直接传递给下一个函数,然后将它们同时设置为状态,这似乎是更好的选择。