React 中的 state 和 props 有什么区别?

IT技术 javascript reactjs
2021-01-15 08:53:51

我正在观看有关 React 的 Pluralsight 课程,讲师说不应更改props。我现在正在阅读一篇关于 props vs. state的文章(uberVU/react-guide),它说

props 和 state 的变化都会触发渲染更新。

文章后面说:

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

  • 那么 props 可以改变,但它们应该是不可变的?
  • 什么时候应该使用 props,什么时候应该使用 state?
  • 如果你有一个 React 组件需要的数据,它应该通过 props 传递还是通过 React 组件中的 setup getInitialState
6个回答

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

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

父母的状态值childsName成为孩子的this.props.name从孩子的角度来看,名称props是不可变的。如果需要更改,父级应该只更改其内部状态:

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

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

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

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

handleName: function(newName) {
   this.setState({ childsName: newName });
}
归结一点:状态是从内部管理的组件数据,道具是从上面管理并传入的组件数据。
2021-03-22 08:53:51
谢谢!所以还有几个问题: 1. 为什么人们说道具不应该改变?2. 你把数据引导放在哪里?在像getInitialState这样的组件的初始化中,还是把它放在组件之外,在有数据的时候渲染组件?
2021-04-01 08:53:51
是的,Flux 存储是客户端缓存。还有其他模式,例如最近发布的 Relay,来自 Facebook 和 Redux。
2021-04-02 08:53:51
所以商店就像大的全局变量?
2021-04-04 08:53:51
1. 这是 React 的“功能性”方面。所有数据(几乎)都向下流动。由于道具归父级所有,因此只有父级应该更改它。理想情况下,儿童应该是无国籍的。这在实践中是不可能的(请参阅 React 站点上的表单文档)。2. 您可以将其放入顶部(推荐做法),也可以将其存放在单独的对象中。一种流行的方法是 Flux,它使用称为 Stores 的单例对象。这是更大的架构模式的一部分。它也是从 Facebook 开源的,旨在与 React 一起使用。
2021-04-06 08:53:51

亲子交流,简单的传递props。

使用state将当前页面需要的数据存储在控制器视图中。

使用props将数据和事件处理程序传递给您的子组件。

这些列表应该有助于指导您处理组件中的数据。

props

  • 是不可变的
    • 这让 React 可以进行快速的参考检查
  • 用于从视图控制器向下传递数据
    • 你的顶级组件
  • 有更好的表现
    • 使用它来将数据传递给子组件

状态

  • 应该在您的视图控制器中管理
    • 你的顶级组件
  • 是可变的
  • 性能更差
  • 不应从子组件访问
    • 用props代替

对于没有父子关系的两个组件之间的通信,您可以设置自己的全局事件系统。在 componentDidMount() 中订阅事件,在 componentWillUnmount() 中取消订阅,并在收到事件时调用 setState()。通量模式是一种可能的安排方式。- https://facebook.github.io/react/tips/communicate-between-components.html

哪些组件应该有状态?

你的大部分组件应该简单地从 props 中获取一些数据并渲染它。但是,有时您需要响应用户输入、服务器请求或时间的流逝。为此,您使用状态。

尝试使尽可能多的组件保持无状态通过这样做,您可以将状态隔离到最合乎逻辑的位置并最大限度地减少冗余,从而更容易推理您的应用程序。

一个常见的模式是创建几个只呈现数据的状态组件,并在层次结构中在它们上面有一个有状态的组件,通过 props 将其状态传递给它的子级。有状态组件封装了所有的交互逻辑,而无状态组件则负责以声明方式呈现数据。- https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#what-c​​omponents-should-have-state

国家应该怎么办?

状态应包含组件的事件处理程序可能会更改以触发 UI 更新的数据。在实际应用中,这些数据往往非常小且可通过 JSON 序列化。在构建有状态组件时,请考虑其状态的最小可能表示,并且仅将这些属性存储在 this.state 中。在 render() 内部,只需根据此状态计算您需要的任何其他信息。你会发现以这种方式思考和编写应用程序往往会导致最正确的应用程序,因为向状态添加冗余或计算值意味着你需要明确地保持它们同步,而不是依赖 React 为你计算它们。- https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#what-should-go-in-state

你能告诉我为什么道具比状态更有表现力吗?谢谢。
2021-03-14 08:53:51
@Dickens 是的,状态用于存储将通过用户交互更改的数据。但它也可用于存储其他变化的信息,例如来自 API 的实时数据。
2021-03-21 08:53:51
@hqt 我认为因为它是不可变的,所以它们内部比较改变值更快
2021-03-29 08:53:51
@BentOnCoding,美好的一天,请你帮忙。我可以想象这样的状态 任何时候用户交互上的组件内的数据都会发生变化,这就是使用状态的地方吗?
2021-04-02 08:53:51
不同意,使用所有道具实际上传递数据的性能较低。只需为子组件设置存储,那么您就不必处理一堆道具,当道具更改时,您必须更新您的组件。只需更新您的商店并让组件从其商店获取其数据。
2021-04-05 08:53:51

您可以通过将它与普通 JS 函数相关联来最好地理解它。

简单的说,

状态是组件的本地状态,不能在组件外部访问和修改。它相当于函数中的局部变量。

普通JS函数

const DummyFunction = () => {
  let name = 'Manoj';
  console.log(`Hey ${name}`)
}

react组件

class DummyComponent extends React.Component {
  state = {
    name: 'Manoj'
  }
  render() {
    return <div>Hello {this.state.name}</div>;
  }

另一方面,Props使组件能够以 props 的形式从其父组件接收数据,从而使组件可重用。它们等价于函数参数。

普通JS函数

const DummyFunction = (name) => {
  console.log(`Hey ${name}`)
}

// when using the function
DummyFunction('Manoj');
DummyFunction('Ajay');

react组件

class DummyComponent extends React.Component {
  render() {
    return <div>Hello {this.props.name}</div>;
  }

}

// when using the component
<DummyComponent name="Manoj" />
<DummyComponent name="Ajay" />

学分:Manoj Singh Negi

文章链接:React State vs Props 解释

React component = plain JS function 是清楚解释这一点的绝妙方法。随着 React 越来越多地转向功能组件,情况变得更加真实。
2021-03-14 08:53:51
这实际上是一个非常有用的答案。读完这篇,我才能理解更完整的答案。谢谢。
2021-03-26 08:53:51

我最喜欢的 props vs state 总结在这里:react-guide给那些家伙的大帽子提示。以下是该页面的编辑版本:


props与状态

tl;dr如果组件需要在某个时间点更改其属性之一,则该属性应该是其状态的一部分,否则它应该只是该组件的props。


props

props(属性的简称)是组件的配置。就接收它们的组件而言,它们是从上面接收的并且是不可变的。一个 Component 不能改变它的 props,但它负责把它的子组件的 props 放在一起。props不必只是数据——回调函数可以作为props传入。

状态

状态是一种数据结构,在组件挂载时以默认值开始。它可能会随着时间发生变化,主要是由于用户事件。

组件在内部管理自己的状态。除了设置初始状态外,它没有必要摆弄子级的状态。您可能将状态概念化为该组件的私有状态。

改变props和状态

                                                   props状态
    可以从父组件获取初始值吗?是的是的
    可以由父组件更改吗?是 否
    可以在组件内部设置默认值吗?* 是 是
    Component里面可以改吗?否 是
    可以为子组件设置初始值吗?是的是的
    可以更改子组件吗?是 否
  • 请注意,从父项接收的 props 和 state 初始值都会覆盖组件内定义的默认值。

这个组件应该有状态吗?

状态是可选的。由于状态会增加复杂性并降低可预测性,因此最好使用没有状态的组件。即使在交互式应用程序中你显然不能没有状态,但你应该避免有太多的有状态组件。

组件类型

Stateless Component只有props,没有状态。除了 render() 函数之外,没有太多事情要做。他们的逻辑围绕着他们收到的props展开。这使它们非常易于遵循和测试。

有状态组件props 和 state。当您的组件必须保留某些状态时使用这些。这是客户端-服务器通信(XHR、Web 套接字等)、处理数据和响应用户事件的好地方。这些类型的逻辑应该封装在适量的有状态组件中,而所有可视化和格式化逻辑应该向下游移动到许多无状态组件中。

来源

“从父级收到的状态初始值”是什么意思?据我所知,状态只定义在单个组件的范围内,不能直接从外部更改。
2021-03-23 08:53:51
@MaximKuzmin 我相信这是对采用像“initialColor”这样的道具来初始化像“颜色”这样的状态的常见模式的参考。状态最初从 prop(从父级接收)中获得值,然后继续像常规状态一样运行。将其包含在 state 与 props 的介绍中可能有点令人困惑,但这是一个需要了解的重要模式。
2021-03-27 08:53:51

props(“properties”的缩写)和state都是普通的 JavaScript 对象。虽然两者都持有影响渲染输出的信息,但它们在一个重要方面有所不同:props被传递给组件(类似于函数参数),而状态在组件内管理(类似于在函数中声明的变量)。

所以简单的状态仅限于您当前的组件,但props可以传递给您希望的任何组件......您可以将当前组件状态作为props传递给其他组件......

同样在 React 中,我们有无状态组件,它们只有 props 而没有内部状态......

下面的示例显示了它们在您的应用程序中的工作方式:

父级(全状态组件):

class SuperClock extends React.Component {

  constructor(props) {
    super(props);
    this.state = {name: "Alireza", date: new Date().toLocaleTimeString()};
  }

  render() {
    return (
      <div>
        <Clock name={this.state.name} date={this.state.date} />
      </div>
    );
  }
}

(无状态组件):

const Clock = ({name}, {date}) => (
    <div>
      <h1>{`Hi ${name}`}.</h1>
      <h2>{`It is ${date}`}.</h2>
    </div>
);