React is pretty flexible but it has a single strict rule: all React components must act like pure functions with respect to their props.
为什么?
我想,如果直接更改props的值,组件就不会重新渲染,这就是为什么我们必须使用setState
。但我仍然不明白这背后的原因。为什么组件在道具方面必须像纯函数一样?
React组件的重要概念是:组件应该只管理自己的状态,但不应该管理自己的道具。
事实上,组件的道具具体地说是"另一个组件(父组件(的状态">。所以道具必须由其组件所有者来管理这就是为什么所有React组件都必须像纯函数一样对待它们的道具(而不是直接改变它们的道具(
我将向您展示一个简单的示例:
class ParentComponent extends Component {
constructor(props) {
super(props);
this.state = {
p1: {a:1, b:2},
}
render() {
return <ChildComponent p1={this.state.p1} />
}
}
在ChildComponent中,如果你想突变"传递的道具p1"(p1是一个有自己引用的对象((例如,在ChildComponent,你写:p1.a=3
(,那么很明显,"ParentComponent的状态的p1属性"也发生了突变。但是在这种情况下,ParentComponent无法重新渲染,因为您没有在ParentComponent中触发动作setState()
因此它会为不稳定的React应用程序生成许多不受控制的错误
我希望现在你能理解React为什么说:
严格的规则是:所有React组件都必须像纯函数一样对待它们的道具(不要直接改变它们的道具(
奖金:要正确更改(更改(道具,您必须在ChildComponent中使用"callback fnc prop"。目前,它非常尊重React Component的概念。
class ParentComponent extends Component {
constructor(props) {
super(props);
this.state = {
p1: {a:1, b:2},
}
this.changeP1 = () => {
this.setState({p1: {a:3, b:4}});
}
render() {
return <ChildComponent p1={this.state.p1} changeP1={this.changeP1} />
}
}
docs
React文档称
所有React组件在道具方面都必须表现得像纯函数当然,应用程序UI是动态的,并且会随着时间的推移而变化。在下一节中,我们将介绍"状态"的一个新概念。State允许React组件随着时间的推移更改其输出,以响应用户操作、网络响应和其他任何事情,而不违反此规则。