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

15

React文档中提到: React非常灵活,但它有一个单一的严格规则:所有React组件在props方面都必须像纯函数一样运作。

为什么如此呢?

我猜如果直接更改props的值,组件不会重新渲染,这就是为什么我们必须使用setState。但我仍然不明白背后的原因。为什么组件必须在props方面像纯函数一样呢?


1
我认为他们之所以想要单向流动是为了避免歧义。 - Revansiddh
2
可能是重复的问题:为什么我不能在React.js中更新props? 另一个可能的重复问题: https://dev59.com/61YN5IYBdhLWcg3wZ3hm?rq=1 - Revansiddh
可能是为什么React props是不可变的的重复问题。 - Shubham Khatri
Props 是我们从一个组件传递到另一个组件的东西,而且有可能 props 被传递给多个组件。如果我们允许一个组件直接更新 props,那么它将渲染所有传递了该 props 的子组件,这可能不是预期的结果,但在某些项目场景下可能会起作用。 - Milind Agrawal
2个回答

8
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} />     
   }
}

在ChildComponent中,如果您想要改变“传递的属性p1”(p1是一个带有自己引用的对象)的值(例如,在ChildComponent中,您编写:p1.a = 3),那么显然,“ParentComponent状态中的p1属性”也会被改变。但是在这种情况下,ParentComponent无法重新呈现,因为您没有在ParentComponent中触发setState()操作。因此,对于不稳定的React应用程序,它将生成许多不受控制的错误。

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

严格规则:所有React组件必须像对待其props的纯函数一样运行(不能直接更改其props)。


奖励部分:为了正确更改(改变)props,您必须在ChildComponent中使用“回调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} />     
   }
}

0

文档

React 文档中提到

所有的 React 组件都必须像对待它们的 props 一样纯函数。 当然,应用程序的 UI 是动态的,并且随着时间的推移而改变。在下一节中,我们将介绍一个新概念“状态”。状态允许 React 组件根据用户操作、网络响应和其他任何事情随时间改变其输出,而不违反此规则。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接