React-native 阻止函数异步执行?
React-native prevent functions from executing asynchronously?
在我的 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
},
setState
不保证是同步的,所以你不能依赖它之后立即更新的状态。
见https://facebook.github.io/react/docs/component-api.html
setState()
does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.
There is no guarantee of synchronous operation of calls to setState
and calls may be batched for performance gains.
API 确实提供了状态实际更新时的回调:
void setState(
function|object nextState,
[function callback]
)
或者,您可以将 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.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
)传递给需要它的函数,而不是使用 field/property:
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()
将新值直接发送到 Firebase,而不是先下载整个数组,然后将其发送回去并添加一个新项目:
onSubmitPressed: function() {
if (this.checkSolution) {
itemsListRef.child(this.state.itemID).push(...);
}
},
在我的 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
},
setState
不保证是同步的,所以你不能依赖它之后立即更新的状态。
见https://facebook.github.io/react/docs/component-api.html
setState()
does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value.There is no guarantee of synchronous operation of calls to
setState
and calls may be batched for performance gains.
API 确实提供了状态实际更新时的回调:
void setState(
function|object nextState,
[function callback]
)
或者,您可以将 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.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
)传递给需要它的函数,而不是使用 field/property:
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()
将新值直接发送到 Firebase,而不是先下载整个数组,然后将其发送回去并添加一个新项目:
onSubmitPressed: function() {
if (this.checkSolution) {
itemsListRef.child(this.state.itemID).push(...);
}
},