Props
props被传递到组件中 这是一个示例(来自的React Guide代码)
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
const element = <Welcome name="Sara" />;
示例代码中的<Welcome name="Sara" />创建了一个name具有 value的属性"Sara"。这里看起来其实有点相像是函数调用...
属性被传递给组件,类似于如何将参数传递给函数。事实上我们确实可以将组件用函数方式重写,这是定义一个组件Component最简单的方式。如下所示:
function Welcome(props) {
return <h1>Hello {props.name}</h1>;
}
一个组件即使没有传递props它仍然可以通过给组件添加defaultProps来设置可选的props:
class Welcome extends React.Component {
render() {
return <h1>Hello {this.props.name}</h1>;
}
}
Welcome.defaultProps = {
name: "world",
};
所以说组件的props既可以来自于父级,也可以由组件本身设置。
关于props最后需要注意的一点,它不应该被改变!在组件的生命周期中props不应更改。我们可以将任何仅使用props的React组件视为“纯”组件,也就是说在给定相同输入的情况下,它将始终呈现相同的输出。
State
Props,State都是保存有关组件的信息,但这两者信息处理方式是不同的。
当组件需要在渲染之间跟踪某些信息,利用State我们就可以在组件中创建、更新、使用我们希望得到的信息。
我将使用一个相当简单的组件来查看state的实际工作方式,通过一个按钮来记录点击它的次数:
class Button extends React.Component {
constructor() {
super();
this.state = {
count: 0,
};
}
updateCount() {
this.setState((prevState, props) => {
return { count: prevState.count + 1 }
});
}
render() {
return (<button
onClick={() => this.updateCount()}
>
Clicked {this.state.count} times
</button>);
}
}
通过这个例子,我们可以看到props和state的第一个真正区别是:
1. state在组件中创建
constructor() {
super();
this.state = {
count: 0,
};
}
constructor构造函数是state获取初始数据的地方,可以自定义默认数据,也可以使用props来初始化state数据。
看似有些矛盾但也是有道理的,印证了我们不能改变props的,如果你想要将组件接收到的数据做一些处理时,就可以将props值初始化给state然后更新state值并使用state。
2. state是多变的
updateCount() {
this.setState((prevState, props) => {
return { count: prevState.count + 1 }
});
}
我们通过更改状态count来跟踪按钮点击次数。setState是非常重要的,首先可以看到setState接收来一个函数,这里是因为setState可以异步运行,它需要一个回调函数而不是直接更新状态。我们可以在回调中访问prevState,这里包含以前的状态信息。
setState更新状态对象并自动重新渲染组件,我们不需要担心重复渲染问题,react会处理这一切!react会在很多情况下静默的使用state的批更新机制使得性能得到保证。
⚠setState警告1:
// 不要这样做!
this.state.count = this.state.count + 1
React无法监听以这种方式更新的状态,因此您的组件不会重新渲染。你应该使用setState
⚠setState警告2:
// 不要这样做!
this.setState({
count: this.state.count + 1
});
虽然这看起来很合理,也不会引发错误跑抛出,但这是错误的用法。这里没有考虑到异步特性,可能会导致数据的不同步。
现在我们来看一下完整流程:
- 组件已初始化
state.count设置为0
this.state = {
count: 0,
};
- 组件显示为,“Clicked 0 times” 作为按钮的文本
Clicked {this.state.count} times
- 用户点击按钮
updateCount被调用,方法绑定到组件的这个实例上
onClick={() => this.updateCount()}
updateCount通过回调调用setState在先前状态的值上增加
this.setState((prevState, props) => {
return { count: prevState.count + 1 }
});
- setState触发render,组件呈现 “Clicked 1 times” 作为按钮文本
Clicked {this.state.count} times
小结
虽然props和state两者都保存着与组件有关的信息,但它们的使用方式不同,应该分开保存。
props包含父组件设置的信息(也可以自己设置默认值)并不应该更改。
state包含组件自己出实话、更改和使用的私有信息。保留的是一种在交互过程中,随时间变化的数据