【发布时间】:2017-07-21 23:43:20
【问题描述】:
它们到底是什么意思?如果我正确理解it,则在计算新状态时不能使用this.state,除非我将函数作为第一个参数传递给setState():
// Wrong
this.setState({a: f(this.state)});
// Correct
this.setState(prevState => {return {a: f(prevState)}});
但我可以使用this.state 来决定要做什么:
if (this.state.a)
this.setState({b: 2});
道具呢?
// Correct or wrong?
this.setState({name: f(this.props)});
据说我不能指望this.state 在调用this.setState 后会改变:
this.setState({a: 1});
console.log(this.state.a); // not necessarily 1
然后,假设我有一个用户列表。还有一个我可以让一个用户成为当前用户的选择:
export default class App extends React.Component {
...
setCurrentUserOption(option) {
this.setState({currentUserOption: option});
if (option)
ls('currentUserOption', option);
else
ls.remove('currentUserOption');
}
handleAddUser(user) {
const nUsers = this.state.users.length;
this.setState(prevState => {
return {users: prevState.users.concat(user)};
}, () => {
// here we might expect any number of users
// but if first user was added, deleted and added again
// two callbacks will be called and setCurrentUserOption
// will eventually get passed a correct value
// make first user added current
if ( ! nUsers)
this.setCurrentUserOption(this.userToOption(user));
});
}
handleChangeUser(user) {
this.setState(prevState => {
return {users: prevState.users.map(u => u.id == user.id ? user : u)};
}, () => {
// again, we might expect any state here
// but a sequence of callback will do the right thing
// in the end
// update value if current user was changed
if (_.get(this.state, 'currentUserOption.value') == user.id)
this.setCurrentUserOption(this.userToOption(user));
});
}
handleDeleteUser(id) {
this.setState(prevState => {
return {users: _.reject(prevState.users, {id})};
}, () => {
// same here
// choose first user if current one was deleted
if (_.get(this.state, 'currentUserOption.value') == id)
this.setCurrentUserOption(this.userToOption(this.state.users[0]));
});
}
...
}
在应用批量更改状态后,所有回调是否都按顺序执行?
再想一想,setCurrentUserOption 基本上就像setState。它将更改排入this.state。即使按顺序调用回调,我也不能依赖 this.state 被先前的回调更改,可以吗?所以最好不要提取setCurrentUserOption方法:
handleAddUser(user) {
const nUsers = this.state.users.length;
this.setState(prevState => {
let state = {users: prevState.users.concat(user)};
if ( ! nUsers) {
state['currentUserOption'] = this.userToOption(user);
this.saveCurrentUserOption(state['currentUserOption']);
}
return state;
});
}
saveCurrentUserOption(option) {
if (option)
ls('currentUserOption', option);
else
ls.remove('currentUserOption');
}
这样我就可以免费排队更改currentUserOption。
【问题讨论】:
-
仔细检查一下您是否使用了任何状态管理框架,例如 redux 或 Flux?答案可能会有所不同
-
我要去。但现在我想让它在没有
redux的情况下工作。
标签: javascript reactjs asynchronous setstate