React中的状态和道具有什么区别?

ska*_*v85 493 javascript reactjs

我正在观看关于React的Pluralsight课程,导师说道具不应该改变.我现在正在阅读一篇关于道具与状态的文章(uberVU/react-guide),它说

道具和状态更改都会触发渲染更新.

在文章的后面它说:

道具(属性的简称)是组件的配置,如果可以的话,它的选项.他们是从上面收到的,不可改变的.

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

Tod*_*odd 613

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

<MyChild name={this.state.childsName} />
Run Code Online (Sandbox Code Playgroud)

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

this.setState({ childsName: 'New name' });
Run Code Online (Sandbox Code Playgroud)

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

<MyChild name={this.state.childsName} onNameChanged={this.handleName} />
Run Code Online (Sandbox Code Playgroud)

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

handleName: function(newName) {
   this.setState({ childsName: newName });
}
Run Code Online (Sandbox Code Playgroud)

  • 这是React的"功能"方面.所有数据(几乎)都向下流动.由于prop由父级拥有,因此只有父级才能更改它.理想情况下,儿童应该是无国籍的.这在实践中是不可能的(参见React网站上的表单文档).2.您可以在顶部输入,这是推荐的做法,或者您可以将其存储在单独的对象中.一种流行的方法是Flux,它使用名为Stores的单件对象.这是更大的建筑模式的一部分.它也是从Facebook开源的,旨在与React合作. (33认同)
  • 归结为一点:状态是从内部管理的组件数据,道具是从上方管理并传入的组件数据。 (4认同)
  • 所以商店就像大的全局变量? (3认同)
  • 谢谢!所以还有另外两个问题:1.人们为什么说道具不应该改变?2.您将数据引导放在何处?在像getInitialState这样的组件初始化中,还是将其放在组件外部并在数据可用时呈现组件? (2认同)
  • 是的,Flux商店是客户端缓存.还有其他模式,如最近发布的Relay,来自Facebook和Redux. (2认同)
  • 可以在http://codepen.io/kang/pen/Pqxyqr上看到相同的工作示例 (2认同)

Ben*_*ing 198

对于亲子沟通,只需传递道具.

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

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

在处理组件中的数据时,这些列表可以帮助指导您.

道具

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

州

  • 应该在您的视图控制器中进行管理
    • 你的顶级组件
  • 是可变的
  • 表现更差
  • 不应从子组件访问
    • 用道具把它传下去

对于没有父子关系的两个组件之间的通信,您可以设置自己的全局事件系统.订阅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

  • 我的答案中的所有内容都直接来自反应文档...... (3认同)
  • 不同意,使用所有道具实际上传递数据的性能较低。只需为子组件设置存储,那么您就不必处理一堆道具,当道具更改时,您必须更新您的组件。只需更新您的商店并让组件从其商店获取其数据。 (2认同)

小智 48

大多数答案都让初学者感到困惑而不是澄清.关联和理解非常困难.你可以通过将它与Plain JS联系起来来理解它.

简单来说,

状态被称为组件的本地状态,该组件无法在组件外部进行访问和修改,只能在组件内部使用和修改.

简单的JS

const DummyFunction = () => {
  let name = 'Manoj';
  console.log(`Hey ${name}`)
}
Run Code Online (Sandbox Code Playgroud)

React JS等效

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

另一方面,道具通过使组件能够以道具的形式从父组件接收数据来使组件可重用.

简单的JS

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

// when using the function
DummyFunction('Manoj');
DummyFunction('Ajay');
Run Code Online (Sandbox Code Playgroud)

反应JS

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

}

// when using the component
<DummyComponent name="Manoj" />
<DummyComponent name="Ajay" />
Run Code Online (Sandbox Code Playgroud)

致谢:https://medium.com/@manojsinghnegi

文章Linke:https://medium.com/@manojsinghnegi/react-state-vs-props-explained-51beebd73b21

  • 这实际上是一个非常有用的答案.读完之后,我就能理解更完整的答案.谢谢. (11认同)
  • React 组件 = 普通 JS 函数是清楚解释这一点的绝妙方法。随着 React 越来越向函数式组件发展,这种情况变得更加真实。 (4认同)

bro*_*eib 40

我最喜欢的道具与州摘要在这里:https://github.com/uberVU/react-guide/blob/master/props-vs-state.md这些家伙的大帽子提示.以下是该页面的编辑版本:


道具与国家

tl; dr如果Component需要在某个时间点改变其中一个属性,那么该属性应该是其状态的一部分,否则它应该只是该Component的prop.


道具

道具(属性的简称)是Component的配置.它们是从上面接收的,并且就接收它们的组件而言是不可变的.组件不能更改其道具,但它负责将其子组件的道具放在一起.道具不必只是数据 - 回调函数可以作为道具传递.

州

状态是一个数据结构,在组件安装时以默认值开始.它可能会随着时间的推移而发生变化,主要是由于用户事件.

组件在内部管理自己的状态.除了设置一个初始状态,它没有摆弄其子女的状态.您可以将状态概念化为该组件的私有状态.

改变道具和状态

                                                   props   state
    Can get initial value from parent Component?    Yes     Yes
    Can be changed by parent Component?             Yes     No
    Can set default values inside Component?*       Yes     Yes
    Can change inside Component?                    No      Yes
    Can set initial value for child Components?     Yes     Yes
    Can change in child Components?                 Yes     No
  • 请注意,从父级接收的props和state初始值都会覆盖Component中定义的默认值.

这个组件应该有状态吗?

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

组件类型

无状态组件只有道具,没有状态.除了render()函数之外没有太多事情发生.他们的逻辑围绕着他们收到的道具.这使得它们非常易于遵循和测试.

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

来源


Ali*_*eza 13

props("属性"的缩写)和state都是纯JavaScript对象.虽然两者都保存影响渲染输出的信息,但它们在一个重要方面是不同的:道具传递给组件(类似于函数参数),而状态在组件内管理(类似于函数内声明的变量).

所以简单的状态仅限于你当前的组件,但是props可以传递给你想要的任何组件......你可以将当前组件的状态作为prop传递给其他组件......

同样在React中,我们有无状态组件,只有道具而不是内部状态......

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

父(状态完整组件):

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>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

儿童(无国籍组成部分):

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


Aft*_*b22 9

道具和状态之间的主要区别在于,状态是内部的,并且由组件本身控制,而道具是外部的,并且由呈现组件的对象控制。

function A(props) {
  return <h1>{props.message}</h1>
}

render(<A message=”hello” />,document.getElementById(“root”));
Run Code Online (Sandbox Code Playgroud)

class A extends React.Component{  
  constructor(props) {  
    super(props)  
    this.state={data:"Sample Data"}  
  }  
  render() {
    return(<h2>Class State data: {this.state.data}</h2>)  
  } 
}

render(<A />, document.getElementById("root"));
Run Code Online (Sandbox Code Playgroud)

状态VS道具

  • 状态可以更改(可变)
  • 而道具不能(不变)


小智 8

React 中的state和props都用于控制数据到组件中,通常 props 由父组件设置并传递给子组件,并且它们在整个组件中都是固定的。对于将要更改的数据,我们必须使用状态。props 是不可变的,而 state 是可变的,如果你想改变 props,你可以从父组件做,然后将它传递给子组件。


小智 6

Props : Props 只是组件的属性,而 React 组件只不过是一个 javascript 函数。

\n\n
  class Welcome extends React.Component {\n    render() {\n      return <h1>Hello {this.props.name}</h1>;\n    }\n  }\n
Run Code Online (Sandbox Code Playgroud)\n\n

常量元素 = ;

\n\n

这里<Welcome name="Sara" />传递一个对象 {name : \'Sara\'} 作为 Welcome 组件的 props。要将数据从一个父组件传递到子组件,我们使用 props。\nProps 是不可变的。在组件\xe2\x80\x99s生命周期期间,道具不应更改(认为它们是不可变的)。

\n\n

状态:状态只能在组件内访问。为了跟踪组件内的数据,我们使用状态。我们可以通过setState来改变状态。如果我们需要将状态传递给孩子,我们必须将其作为道具传递。

\n\n
class Button extends React.Component {\n  constructor() {\n    super();\n    this.state = {\n      count: 0,\n    };\n  }\n\n  updateCount() {\n    this.setState((prevState, props) => {\n      return { count: prevState.count + 1 }\n    });\n  }\n\n  render() {\n    return (<button\n              onClick={() => this.updateCount()}\n            >\n              Clicked {this.state.count} times\n            </button>);\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n


Ras*_*bal 6

正如我在使用 react 时学到的。

  • 组件使用props从外部环境获取数据,即另一个组件(纯、函数或类)或通用类或javascript/typescript代码

  • 状态被用于管理的一个组件的内部环境的装置的数据改变内部部件


Nes*_*ric 5

基本上,区别在于状态类似于OOP中的属性:状态是类(组件)的局部内容,用于更好地描述状态。道具就像参数一样 -它们是从组件的调用者(父对象)传递到组件的:就像您使用某些参数调用函数一样。


Aka*_*ore 5

状态:

  1. 状态是可变的。
  2. 状态与单个组件相关联,不能被其他组件使用。
  3. 状态在组件安装时初始化。
  4. 状态用于呈现组件内的动态变化。

道具:

  1. props 是不可变的。
  2. 您可以在组件之间传递道具。
  3. props 主要用于组件之间的通信。可以直接从父级传递给子级。为了从孩子传递给父母,您需要使用提升状态的概念。

class Parent extends React.Component{
  render()
  {
     return(
        <div>
            <Child name = {"ron"}/>
        </div>
      );
  }
}

class Child extends React.Component{
{
    render(){
      return(
         <div>
              {this.props.name}
        </div>
      );
     }
}
Run Code Online (Sandbox Code Playgroud)