为什么React中的道具是只读的?

L. *_*rto 5 pure-function reactjs

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。但我仍然不了解其背后的原因。为什么组件在其道具方面必须像纯函数一样?

San*_*ika 7

React 组件的重要概念:一个组件应该只管理自己的状态,而不应该管理自己的 props。

实际上,一个组件的 props 具体就是“另一个组件(父组件)的状态”。所以 props 必须由它们的组件所有者管理。这就是为什么所有 React 组件在它们的 props 方面都必须像纯函数一样(而不是直接改变它们的 props)。

我将向您展示一个简单的例子:

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

   render() {
      return <ChildComponent p1={this.state.p1} />     
   }
}
Run Code Online (Sandbox Code Playgroud)

在 ChildComponent 中,如果你想改变“passed prop p1”(p1 是一个有他自己的 ref 的对象)(例如在 ChildComponent 中,你写:)p1.a=3,那么显然,“p1 - ParentComponent 状态的属性”也变异了。但是在这种情况下 ParentComponent 无法重新渲染,因为您没有触发setState()ParentComponent 中的操作。所以它会为一个不稳定的 React App 产生许多不受控制的错误。

我希望现在你能理解 React 为什么说:

严格的规则:所有 React 组件在它们的 props 方面必须像纯函数一样(不要直接改变它们的 props)。


奖励:为了正确更改(变异)道具,您必须在 ChildComponent 中使用“回调 fnc 道具”。现在,它很好地尊重了 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} />     
   }
}
Run Code Online (Sandbox Code Playgroud)