Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

状态管理(this.state)篇 #1

Open
oliver1204 opened this issue Jun 4, 2018 · 3 comments
Open

状态管理(this.state)篇 #1

oliver1204 opened this issue Jun 4, 2018 · 3 comments

Comments

@oliver1204
Copy link
Owner

oliver1204 commented Jun 4, 2018

  1. State 的更新是异步的。

调用setState,组件的state并不会立即改变,setState只是把要修改的状态放入一个队列中,React会优化真正的执行时机,并且React会出于性能原因,可能会将多次setState的状态修改合并成一次状态修改。所以不要依赖当前的State,计算下个State。

// 不建议
this.setState({quantity: this.state.quantity + 1})

// 正确
this.setState((preState, props) => {
  counter: preState.quantity + 1; 
})
  1. 状态的类型是数组
// 方法一:将state先赋值给另外的变量,然后使用concat创建新数组
var books = this.state.books; 
this.setState({
  books: books.concat(['React Guide']);
})

// 方法二:使用preState、concat创建新数组
this.setState(preState => ({
  books: preState.books.concat(['React Guide']);
}))

// 方法三:ES6 spread syntax
this.setState(preState => ({
  books: [...preState.books, 'React Guide'];
}))
  1. 状态的类型是普通对象(不包含字符串、数组)
    3.1 使用ES6 的Object.assgin方法
// 方法一:将state先赋值给另外的变量,然后使用Object.assign创建新对象
var owner = this.setState.owner;
this.setState({
  owner: Object.assign({}, owner, {name: 'Jason'});
})

// 方法二:使用preState、Object.assign创建新对象
this.setState(preState => ({
  owner: Object.assign({}, preState.owner, {name: 'Jason'});
}))

3.2 使用对象扩展语法

// 方法一:将state先赋值给另外的变量,然后使用对象扩展语法创建新对象
var owner = this.setState.owner;
this.setState({
  owner: {...owner, {name: 'Jason'}};
})

// 方法二:使用preState、对象扩展语法创建新对象
this.setState(preState => ({
  owner: {...preState.owner, {name: 'Jason'}};
}))

总结一下,创建新的状态对象的关键是,避免使用会直接修改原对象的方法,而是使用可以返回一个新对象的方法。

@oliver1204
Copy link
Owner Author

oliver1204 commented Aug 1, 2018

几篇个人认为比较好的文章

所有通过react生命周期阶段调用的setstate都是非同步的,因为每次setstate都会触发更新阶段的生命周期所以按照正常react用法都是会经过batchingUpdate方法的。这是由于react有一套自定义的事件系统和生命周期流程控制,使用原生事件监听和settimeout这种方式会跳出react这个体系,所以会直接更新this.state。

@oliver1204
Copy link
Owner Author

oliver1204 commented Aug 2, 2018

附上一张react 生命周期图好不好,不过16.0 中新添的 componentDidCatch 和 16.3 新添的getDerivedStateFromProps、getSnapshotBeforeUpdate 不在其中。

image

v16.3 后的生命周期图

image

v16.4 后的生命周期图

image

具体缘由

@oliver1204
Copy link
Owner Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant