接触过Vue的,应该对prop和state不陌生,父类通过prop向子类传递数据,state是Vuex状态管理的状态值。React也差不多,prop是同样组件的对外接口,不同是state是组件的内部状态管理,相当于Vue的data。简单来说对外用prop,内部用state。且无论prop或者state的改变,都可能引起组件的重新渲染。
prop
在 React 中, prop ( property 的简写)是从外部传递给组件的数据, 一个 React 组件 通过定义自己能够接受的 prop 就定义了自己的对外公共接口 。每个 React组件都是独立存在的模块,组件之外的一切都是外部世界,外部世界就是通过 prop 来和组件对话的 。
prop传值
例如:给DemoComponent组件传值:1
<DemoComponent data="demo" loading={true} style={{ marginTop: 16 }} />
prop读取
1.构造函数传入
1 | class DemoComponent extends Component { |
2.this
组件函数内可直接调用this.props
访问。
1 | class DemoComponent extends Component { |
1
2
3
4
5
6
7
8
9
10
11render() {
const { data } = this.props;
return (
<div>
<p>{data}</p>
{/* <p>{this.props.data}</p> */}
{/* 直接调用也不是不可以 */}
</div>
)
}
propTypes
用于检查props类型,直观查看组件支持那些prop,当然也可以写在注释里面。如果数据不符合约定规范会报出警告⚠️,但不会影响代码执行。推荐只用于开发环境,避免传值犯错。
DEMO:
1 | class DemoComponent extends Component { |
详细说明可见->Typechecking With PropTypes
state
驱动组件渲染过程的除了 prop,还有 state, state 代表组件的内部状态 。 由于 React 组件不能修改传入的 prop,所以需要记录自身数据变化,就要使用 state。
初始化state
1.构造函数中初始化,如上述案列:
1 | constructor (props) { |
2.defaultProps
1 | class DemoComponent extends Component { |
读取于更新state
在代码中,通过 this.state 可以读取到组件的当前 state。 值得注意的是,我们改变组 件 state 必须要使用 this.setState 函数,而不能直接去修改 this.state。
DEMO:1
2
3
4
5
6
7
8
9
10
11class DemoComponent extends Component {
...
demo = () => {
console.log(this.state.data); // demo
this.setState({
data: "changed"
});
console.log(this.state.data); // changed
}
...
}
对比
prop | state |
---|---|
定义外部接口 | 记录内部状态 |
外部赋值 | 内部赋值 |
内部不改变数据(只读) | 组件状态值(读写) |
不管是Vue还是React都不推荐、不应该组件内直接修改传入的props值。之前实现的props数据双向传递,原理也是通过子组件的函数回调,修改父组件的值,从而改变的props原值。
局限性
单个组件还可以,数据低耦合,只关系到组件内部。但是如果是类似全局状态,子组件存储记录,父组件也存储记录,数据重复。重复之后一致性就很难得到保证。相同的状态,分别存放在不同组件中,很难统一,这时候就需要一个全局状态来同步管理这些数据。让各个组件保持和全局状态的一致,更容易控制。这时我们就需要全局状态管理 Flux 和 Redux 中 Store 的概念。
其他
《深入浅出React和Redux》 前几天群里有人推荐的,正好也需要一本React书,感觉还可以。
参考:《深入浅出React和Redux》- React组件的数据