我在看Pluralsight关于React的课程,老师说道具不应该被改变。我现在正在读一篇关于道具vs.国家的文章(uberVU/react-guide),它说

道具和状态更改都会触发呈现更新。

文章后面说:

Props(属性的缩写)是组件的配置,如果可以的话,是它的选项。它们是从上面接收的,是不可变的。

所以道具可以改变,但它们应该是不可变的? 什么时候应该使用道具,什么时候应该使用状态? 如果你有一个React组件需要的数据,它应该通过道具或设置在React组件通过getInitialState?


当前回答

状态是react处理组件所持有信息的方式。

假设有一个组件需要从服务器获取一些数据。您通常希望通知用户请求是否正在处理,请求是否失败,等等。这是一条与特定组件相关的信息。这就是状态进入游戏的地方。

通常定义状态的最佳方法如下:

class MyComponent extends React.Component {
  constructor() {
    super();
    this.state = { key1: value1, key2: value2 }    
  }
}

但是在react native的最新实现中,你可以这样做:

class MyComponent extends React.Component {
  state = { key1: value1, key2: value2 }    
}

这两个例子以完全相同的方式执行,这只是语法上的改进。

那么,与我们在面向对象编程中总是使用对象属性有什么不同呢?通常,在您的状态中保存的信息并不是静态的,它会随着时间的推移而变化,您的视图需要更新以反映这些变化。State以一种简单的方式提供了此功能。

状态是不可改变的!我再怎么强调也不为过。这意味着什么?这意味着你永远不应该做这样的事情。

 state.key2 = newValue;

正确的做法是:

this.setState({ key2: newValue });

使用这个。setState你的组件在更新周期中运行,如果状态的任何部分发生变化,你的组件呈现方法将被再次调用以反映这些变化。

请查看react文档以获得更详细的解释: https://facebook.github.io/react/docs/state-and-lifecycle.html

其他回答

props是JavaScript对象,传递给组件,保存配置属性。 props是接收组件不可更改的 state是在Component中管理的JavaScript对象,保存它的内部状态。 更新可以触发重新渲染

在React中,道具和状态之间有一些关键的区别。道具是不可变的——一旦设置好,就不能更改。另一方面,状态可以在任何时候改变。道具也从父组件传递给子组件,而状态是单个组件的局部状态。

这是我目前对于状态与道具之间的解释的观点

State就像组件中的局部变量。你可以操纵 使用set state获取state的值。然后可以传递state的值 例如,您的子组件。 Props是位于redux存储中的值 来源于来源于减速器的状态。您的组件 应该连接到redux从道具中获取值。你也可以通过 你的props值给你的子组件

道具和状态在某种程度上是相同的,它们都会触发重渲染。不同之处在于,道具来自于父组件,状态在当前组件中管理。状态是可变的,道具是不可变的

道具和状态是相关的。一个组件的状态通常会成为子组件的道具。道具在父元素的呈现方法中作为React.createElement()的第二个参数传递给子元素,如果您使用的是JSX,则是更熟悉的标记属性。

<MyChild name={this.state.childsName} />

父类的childsName的状态值变成子类的this.props.name。从子进程的角度来看,名称道具是不可变的。如果它需要改变,父进程只需要改变它的内部状态:

this.setState({ childsName: 'New name' });

React会把它传播给你的子程序。一个自然的后续问题是:如果子程序需要更改其名称道具怎么办?这通常是通过子事件和父回调完成的。子进程可能会公开一个名为onNameChanged的事件。然后父进程通过传递回调处理程序来订阅事件。

<MyChild name={this.state.childsName} onNameChanged={this.handleName} />

子进程将通过调用this.props将其请求的新名称作为参数传递给事件回调。onNameChanged('New name'),父进程将在事件处理程序中使用该名称来更新其状态。

handleName: function(newName) {
   this.setState({ childsName: newName });
}