React组件的state和props
React
的数据是自顶向下单向流动的,即从父组件到子组件中,组件的数据存储在props
和state
中。实际上在任何应用中,数据都是必不可少的,我们需要直接的改变页面上一块的区域来使得视图的刷新,或者间接地改变其他地方的数据,在React
中就使用props
和state
两个属性存储数据。
描述
state
的主要作用是用于组件保存、控制、修改自己的可变状态。state
在组件内部初始化,可以被组件自身修改,而外部不能访问也不能修改,可以认为state
是一个局部的、只能被组件自身控制的数据源,state
中状态可以通过this.setState
方法进行更新,setState
会导致组件的重新渲染。
props
的主要作用是让使用该组件的父组件可以传入参数来配置该组件,它是外部传进来的配置参数,组件内部无法控制也无法修改,除非外部组件主动传入新的props
,否则组件的props
永远保持不变。
state
和props
都可以决定组件的行为和显示形态,一个组件的state
中的数据可以通过props
传给子组件,一个组件可以使用外部传入的props
来初始化自己的state
,但是它们的职责其实非常明晰分明,state
是让组件控制自己的状态,props
是让外部对组件自己进行配置。简单来说props
是传递给组件的(类似于函数的形参),而state
是在组件内被组件自己管理的(类似于在一个函数内声明的变量)。
一个清晰的原则是尽量少地用state
,尽量多地用props
,没有state
的组件叫无状态组件stateless component
,设置了state
的叫做有状态组件stateful component
。因为状态会带来管理的复杂性,我们尽量多地写无状态组件,尽量少地写有状态的组件,这样会降低代码维护的难度,也会在一定程度上增强组件的可复用性。
props
React
的核心思想就是组件化思想,页面会被切分成一些独立的、可复用的组件。组件从概念上看就是一个函数,可以接受一个参数作为输入值,这个参数就是props
,所以可以把props
理解为从外部传入组件内部的数据,由于React
是单向数据流,所以props
基本上也就是从服父级组件向子组件传递的数据。
假设我们现在需要实现一个列表,我们把列表中的行当做一个组件,也就是有这样两个组件<ItemList/>
和<Item/>
。列表ItemList
组件的数据我们就暂时先假设是放在一个data
变量中,然后通过map
函数返回一个每一项都是<Item item={数据}/>
的数组,也就是说这里其实包含了data.length
个<Item/>
组件,数据通过在组件上自定义一个参数传递。之后在Item
组件内部是使用this.props
来获取传递到该组件的所有数据,它是一个对象其中包含了所有对这个组件的配置,现在只包含了一个item
属性,所以通过this.props.item
来获取即可。
props
经常被用作渲染组件和初始化状态,当一个组件被实例化之后,它的props
是只读的,不可改变的。如果props
在渲染过程中可以被改变,会导致这个组件显示的形态变得不可预测,只有通过父组件重新渲染的方式才可以把新的props
传入组件中。也就是说props
是一个从外部传进组件的参数,主要作为就是从父组件向子组件传递数据,它具有可读性和不变性,只能通过外部组件主动传入新的props
来重新渲染子组件,否则子组件的props
以及展现形式不会改变。
在组件中,我们也可以为props
中的参数设置一个defaultProps
,并且制定它的类型。
不同的验证器类型如下。
state
一个组件的显示形态可以由数据状态和外部参数所决定,外部参数也就是props
,而数据状态就是state
。state
的主要作用是用于组件保存、控制以及修改自己的状态,它只能在constructor
中初始化,它算是组件的私有属性,不可通过外部访问和修改,只能通过组件内部的this.setState
来修改,修改state
属性会导致组件的重新渲染。简单来说就是在组件初始化的时候,通过this.state
给组件设定一个初始的state
,在第一次render
的时候就会用这个数据来渲染组件。
state
不同于props
的一点是,state
是可以被改变的。不过不可以直接通过this.state= values;
的方式来修改,而需要通过this.setState()
方法来修改state
。例如我们经常会通过异步操作来获取数据,我们需要在didMount
生命周期阶段来执行异步操作。
当我们调用this.setState
方法时,React
会更新组件的数据状态state
,并且重新调用render
方法,也就是会对组件进行重新渲染。setState
接受一个对象或者函数作为第一个参数,只需要传入需要更新的部分即可,setState
还可以接受第二个参数,它是一个函数,会在setState
调用完成并且组件开始重新渲染时被调用,可以用来监听渲染完成。
示例
每日一题
参考