为什么 React 中的 props 是只读的?

Why props in React are read only?

React 文档说: 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。但我仍然不明白这背后的原因。为什么组件在 props 方面必须像纯函数一样?

docs

React 文档说

所有 React 组件在 props 方面都必须像纯函数一样。 当然,应用程序 UI 是动态的,会随时间而变化。在下一节中,我们将介绍一个新的概念“状态”。 State 允许 React 组件随时间更改其输出以响应用户操作、网络响应和其他任何内容,而不会违反此规则。

The important concept of React component: a component should only manage its own state, but it should not manage its own props.

In fact, props of a component is concretely "the state of the another component (parent component)". So props must be managed by their component owner. That's why all React components must act like pure functions with respect to their props (not to mutate directly their props).

我给你看一个简单的例子:

class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      p1: {a:1, b:2},
    }

   render() {
      return <ChildComponent p1={this.state.p1} />     
   }
}

在 ChildComponent 中,如果你想改变 "passed prop p1"(p1 是一个有自己引用的对象)(例如,在 ChildComponent 中,你写:p1.a=3),显然, "the p1 - property of the state of ParentComponent"也变异了。但是在这种情况下 ParentComponent 无法重新渲染,因为您没有在 ParentComponent 中触发操作 setState()所以对于不稳定的 React App 会产生很多不受控制的 bug。

I hope right now that you can understand why React says:

The strict rule: all React components must act like pure functions with respect to their props (not to mutate directly their props).


奖励:要正确更改(变异)道具,您必须在 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} />     
   }
}