2016-05-14 115 views
0

在点击我的反应原生应用的按钮,我调用两个功能:getSolutionListFromDatabase,设定组件的状态以包括此溶液列表,然后updateDatabaseSolutionList,其中将元素添加到该列表,并再将它推回至火力地堡。但是,虽然应用程序的状态在第一个函数中正确更新,但在第二个函数中,状态被记录为未定义,并且在第一个函数中的某些语句之前正在调用该函数的日志语句。由于某些原因,函数是否异步运行,并且这是React native的一个特性?如果是这样,我怎样才能防止第二个功能执行,直到状态被设置?谢谢。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 
}, 

回答

5

逻辑将始终是相同的answer to your previous question。如果您有活动之间的依赖关系,你应该将调用到第一个回调:

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 
}, 

但更好的只会是push()新值直奔火力地堡,而不是先下载整个数组,然后用一个新的项目发送回添加到它:

onSubmitPressed: function() { 
    if (this.checkSolution) { 
     itemsListRef.child(this.state.itemID).push(...); 
    } 
}, 
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到下一个功能,然后在设定他们两个的状态同时,这似乎是更好的选择。

+0

感谢您的提示。当我尝试通过返回snap.val()直接将solutionList传递给下一个函数时,即使它在函数内记录snap.val的正确值,该函数也会返回为未定义的。任何想法可能发生在这里? – user3802348