React基础11 React中初始化state的两种方法
在React的组件中可以在两个位置来初始化state:(1)在组件的constructor中;(2)直接在class中利用属性赋值的方式
在constructor中
在constructor中初始化state如下所示:
1 | class App extends React.Component { |
当一个class组件创建之后,constructor会首先被调用,所以在construcot中可以来初始化所有值,包括state。class实例在内存中已经被创建,所以可以使用this来为state赋值
要注意的是,在constructor中可以不使用this.setState来为state直接赋值,除此之外其他位置都不能这样做:
1 | // 除了在constructor中,其他位置都不要这样做 |
只有通过setState才能通知React,我们修改了数据,React需要重新渲染组件。
还有要注意的是,在constructor中不要忘记使用super(props)来调用父类的constructor。默认的constructor(当创建一个class时,如果我们没有显式的声明constructor,JS会默认提供一个)会自动调用super,将将所有的参数传入
使用prop来初始化state
大多数情况下都不要使用prop来为State的初始化赋值,因为这会让你的数据来源不唯一,这常常会导致Bug。数据源唯一是最佳实践。
当组件的prop发生改变,组件会重渲染,所以没有必要将prop复制为state来保证porp永远是最新的值。
1 | // 不要这样做 |
constructor是必须的吗?
并一定必须显式的定义constructor,因为JS会提供默认的constructor。比如下面这个例子:
1 | class Parent { |
当创建Child的实例时,控制台会打印出constructing Parent with 5,虽然Child类并没有显式的定义constructor,也没有显式的通过super(props)调用父类。当我们没有定义自己的constructor时,JS会自动完成super的步骤。
直接在Class中定义
第二种初始化state的方法就是直接在Class的内部,使用Class的属性来定义:
1 | class App extends React.Component { |
比如使用construcot更加得直接、简介。要注意的是:
- 没有定义
constructor state属性是直接引用的,并不是通过this.state来引用的state的作用域是在Class内部,并不是一个方法的内部- 仍然可以使用
this.props和this.context state是class的实例属性,并不是静态属性,不需要添加static关键字(就像为static propTypes {...})
哪种更好
习惯使用哪种,就使用哪种。
class属性的方式看起来更加简单,不再需要额外的模板代码(constructor),也不需要提醒自己调用super(props)
有的时候需要在constructor中处理事件处理函数(为函数绑定this,就像:
1 | class Thing extends React.Component { |
可以通过Class属性的另外一种形式来替代上面的形式,可以让一个属性等于一个箭头函数,箭头函数获得了class实例的this,所以不再需要在constructor中显式的去绑定:
1 | class Thing extends React.Component { |