首页 文章

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

提问于
浏览
334

我正在看React的Pluralsight课程,导师说道具不应该改变 . 我正在阅读关于道具与国家的an article (uberVU/react-guide),它说

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

在文章的后面它说:

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

  • 所以道具可以改变,但它们应该是不可改变的?

  • 什么时候应该使用道具?什么时候应该使用状态?

  • 如果您有React组件需要的数据,是应该通过 getInitialState 传递道具还是在React组件中设置?

22 回答

  • 1

    状态是你的数据,是可变的,你可以做任何你需要的东西,道具是只读数据,通常当你传递道具你已经处理过你的数据并且你需要子组件来渲染它或者你的道具是函数你叫它执行任务

  • 1

    基本上,区别在于 state 类似于OOP中的属性:它是类(组件)的 local ,用于更好地描述它 . Props 类似于参数 - 它们是来自组件调用者(父类)的组件的 passed :就好像您使用某些参数调用了一个函数 .

  • 1

    道具:道具只是组件的属性,反应组件只是一个javascript函数 .

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

    const element =;

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

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

    class Button extends React.Component {
      constructor() {
        super();
        this.state = {
          count: 0,
        };
      }
    
      updateCount() {
        this.setState((prevState, props) => {
          return { count: prevState.count + 1 }
        });
      }
    
      render() {
        return (<button
                  onClick={() => this.updateCount()}
                >
                  Clicked {this.state.count} times
                </button>);
      }
    }
    
  • 435

    通常,一个组件(父组件)的状态是子组件的prop .

    • State位于一个组件中,其中props从父级传递给子级 .

    • 道具通常是不可变的 .

    class Parent extends React.Component {
        constructor() {
            super();
            this.state = {
                name : "John",
            }
        }
        render() {
            return (
                <Child name={this.state.name}>
            )
        }
    }
    
    class Child extends React.Component {
        constructor() {
            super();
        }
    
        render() {
            return(
                {this.props.name} 
            )
        }
    }
    

    在上面的代码中,我们有一个父类(Parent),其名称作为其状态,作为prop传递给子组件(Child类),子组件使用呈现它

  • 4

    简单的解释是:STATE是组件的局部状态,例如color =“blue”或animation = true等 . 使用this.setState更改组件的状态 . PROPS是组件如何相互通信(将数据从父级发送到子级)并使组件可重用的方式 .

  • 157

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

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

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

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

    Props

    • 是不可变的

    • 让React做快速参考检查

    • 用于从视图控制器传递数据

    • 您的顶级组件

    • 有更好的表现

    • 使用它将数据传递给子组件

    State

    应在视图控制器中管理

    • 您的顶级组件

    • 是可变的

    • 表现较差
      不应从子组件访问

    • 用道具传下来

    对于没有父子关系的两个组件之间的通信,您可以设置自己的全局事件系统 . 订阅componentDidMount()中的事件,取消订阅componentWillUnmount(),并在收到事件时调用setState() . Flux模式是安排这种方式的可能方式之一 . - https://facebook.github.io/react/tips/communicate-between-components.html哪些组件应该具有状态?大多数组件应该只从props中获取一些数据并进行渲染 . 但是,有时您需要响应用户输入,服务器请求或时间的推移 . 为此你使用状态 . 尽量保持尽可能多的组件无状态 . 通过这样做,您可以将状态隔离到最合理的位置并最大限度地减少冗余,从而更容易推理您的应用程序 . 一种常见的模式是创建几个只呈现数据的无状态组件,并在层次结构中有一个有状态的组件,通过props将其状态传递给子节点 . 有状态组件封装了所有交互逻辑,而无状态组件负责以声明方式呈现数据 . - https://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html#what-components-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

  • 0

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

    简单来说,

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

    简单JS

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

    React JS等效

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

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

    简单JS

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

    反应JS

    class DummyComponent extends React.Component {
      render() {
        return <div>Hello {this.props.name}</div>;
      }
    
    }
    // when using the component
    <DummyComponent name="Manoj" />
    <DummyComponent name="Ajay" />
    

    积分:https://medium.com/@manojsinghnegi

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

  • 0

    道具只是简单的属性 . 道具是组件彼此交谈的方式 . 如果您完全熟悉React,那么您应该知道道具从父组件向下流动 .

    还有一种情况是你可以拥有默认道具,这样就可以设置道具,即使父组件没有传递道具 .

    这就是为什么人们将React称为具有单向数据流的原因 . 这需要一点时间,我可能会在稍后博客,但现在只记得:数据从父到子流动 . 道具是不可改变的(花哨的词,因为它不会改变)

    所以我们很高兴 . 组件从父级接收数据 . 全部排序,对吗?

    嗯,不太好 . 当组件从父级以外的其他人接收数据时会发生什么?如果用户直接向组件输入数据怎么办?

    那么,这就是为什么我们有州 .

    道具不应该改变,所以状态升级 . 通常,组件没有状态,因此被称为无状态 . 使用状态的组件称为有状态 . 随意在派对上放下那个小小的花絮,看着别人远离你 .

    因此使用状态,以便组件可以跟踪它所执行的任何渲染之间的信息 . 当您设置State时,它会更新状态对象,然后重新渲染组件 . 这非常酷,因为这意味着React负责这项艰苦的工作并且速度非常快 .

    作为状态的一个小例子,这里是搜索栏的一个片段(如果你想了解更多关于React的话,值得查看这个课程)

    Class SearchBar extends Component {
     constructor(props) {
      super(props);
    this.state = { term: '' };
     }
    render() {
      return (
       <div className="search-bar">
       <input 
       value={this.state.term}
       onChange={event => this.onInputChange(event.target.value)} />
       </div>
       );
     }
    onInputChange(term) {
      this.setState({term});
      this.props.onSearchTermChange(term);
     }
    }
    

    摘要

    道具和州做类似的事情,但以不同的方式使用 . 您的大部分组件可能都是无状态的 .

    道具用于将数据从父级传递给子级或由组件本身传递 . 它们是不可变的,因此不会改变 .

    状态用于可变数据或将改变的数据 . 这对用户输入特别有用 . 以搜索栏为例 . 用户将输入数据,这将更新他们看到的内容 .

  • 0

    在回答关于道具是不可变的最初问题时,就子组件而言,它们被认为是不可变的,但在父组件中是可变的 .

  • 36

    州:

    • 州是可变的 .

    • 状态与其他组件不能使用的各个组件相关联 .

    • 状态在组件安装时初始化 .

    • 状态用于在组件内呈现动态更改 .

    道具:

    • 道具是不可变的 .

    • 你可以在组件之间传递道具 .

    • 道具主要用于组件之间的通信 . 您可以直接从父级传递给子级 . 对于从孩子到父母的传递,您需要使用提升状态的概念 .

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

    state - 它是一个特殊的可变属性,用于保存组件数据 . Componet安装时它具有默认值 .

    props - 这是一种特殊的 property ,它本质上是不可变的,用于从父母到孩子的 Value 转移的情况 . props只是组件之间的通信通道,总是从顶部(父级)移动到buttom(子级) .

    below are complete example of combinding the state & props :-

    <!DOCTYPE html>
        <html>
          <head>
            <meta charset="UTF-8" />
            <title>state&props example</title>
    
            <script src="https://unpkg.com/react@0.14.8/dist/react.min.js"></script>
            <script src="https://unpkg.com/react-dom@0.14.8/dist/react-dom.min.js"></script>
            <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    
          </head>
          <body>
          <div id="root"></div>
            <script type="text/babel">
    
                var TodoList = React.createClass({
                    render(){
                        return <div className='tacos-list'>
                                    {
                                        this.props.list.map( ( todo, index ) => {
                                        return <p key={ `taco-${ index }` }>{ todo }</p>;
                                })}
                                </div>;
                    }
                });
    
                var Todo = React.createClass({
                    getInitialState(){
                        return {
                            list : [ 'Banana', 'Apple', 'Beans' ]       
                        }
                    },
                    handleReverse(){
                        this.setState({list : this.state.list.reverse()});
                    },
                    render(){
                        return <div className='parent-component'>
                                  <h3 onClick={this.handleReverse}>List of todo:</h3>
                                  <TodoList list={ this.state.list }  />
                               </div>;
                    }
                });
    
                ReactDOM.render(
                    <Todo/>,
                    document.getElementById('root')
                );
    
            </script>
          </body>
          </html>
    
  • 3

    我最喜欢的道具vs状态总结就在这里:https://github.com/uberVU/react-guide/blob/master/props-vs-state.md给那些家伙的大帽子小费 . 以下是该页面的编辑版本:


    道具vs州

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


    道具

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

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

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

    改变道具和状态

    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内定义的默认值 .

    此组件是否具有状态?

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

    组件类型

    Stateless Component 只有道具,没有国家 . 除了render()函数之外没有太多事情发生 . 他们的逻辑围绕着他们收到的道具 . 这使得它们非常容易跟踪和测试 .

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

    来源

  • 17

    State是处理组件所持信息的方式 .

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

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

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

    但是在本地反应原理的最新实现中你可以做到:

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

    这两个示例以完全相同的方式执行,它只是语法改进 .

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

    国家意味着无法改变!而且我无法对此施加足够的压力 . 这意味着什么?这意味着你永远不应该做这样的事情 .

    state.key2 = newValue;
    

    正确的做法是:

    this.setState({ key2: newValue });
    

    使用this.setState,组件将运行更新周期,如果状态的任何部分发生更改,则将再次调用Component render方法以反映此更改 .

    查看反应文档以获得更广泛的解释:https://facebook.github.io/react/docs/state-and-lifecycle.html

  • 0

    响应中的 stateprops 都用于将数据控制到组件中,通常道具由父设置并传递给子组件,并且它们在整个组件中是固定的 . 对于 data that is going to change, ,我们必须使用州 . 并且道具是 immutable 而状态是 mutable ,如果你想改变你可以从父组件做的道具然后将它传递给子组件 .

  • 2

    基本上,props和state是组件可以知道什么以及如何呈现的两种方式 . 应用程序状态的哪个部分属于州,哪个属于某个顶级商店,与您的应用程序设计有关,而不是与React的工作方式有关 . 决定IMO的最简单方法是考虑这个特定的数据是否对整个应用程序有用,或者它是一些本地信息 . 此外,重要的是不重复状态,因此如果某些数据可以从道具计算 - 它应该从道具计算 .

    例如,假设您有一些下拉控件(包含标准HTML选择以进行自定义样式),这可以a)从列表中选择一些值,以及b)打开或关闭(即显示或隐藏选项列表) . 现在,假设您的应用程序显示某种项目列表,并且您的下拉列表控件会过滤列表条目 . 然后,最好将活动过滤器值作为道具传递,并保持打开/关闭状态为本地 . 此外,为了使其正常工作,您将从父组件传递一个onChange处理程序,该组件将在dropdown元素内部调用,并立即将更新的信息(新选择的过滤器)发送到商店 . 另一方面,打开/关闭状态可以保留在下拉组件中,因为应用程序的其余部分并不真正关心控件是否打开,直到用户实际更改它的值 .

    以下代码不能完全正常工作,它需要css和处理下拉单击/模糊/更改事件,但我想保持示例最小化 . 希望有助于理解差异 .

    const _store = {
        items: [
        { id: 1, label: 'One' },
        { id: 2, label: 'Two' },
        { id: 3, label: 'Three', new: true },
        { id: 4, label: 'Four', new: true },
        { id: 5, label: 'Five', important: true },
        { id: 6, label: 'Six' },
        { id: 7, label: 'Seven', important: true },
        ],
      activeFilter: 'important',
      possibleFilters: [
        { key: 'all', label: 'All' },
        { key: 'new', label: 'New' },
        { key: 'important', label: 'Important' }
      ]
    }
    
    function getFilteredItems(items, filter) {
        switch (filter) {
        case 'all':
            return items;
    
        case 'new':
            return items.filter(function(item) { return Boolean(item.new); });
    
        case 'important':
            return items.filter(function(item) { return Boolean(item.important); });
    
        default:
            return items;
      }
    }
    
    const App = React.createClass({
      render: function() {
        return (
                <div>
                My list:
    
                <ItemList   items={this.props.listItems} />
              <div>
                <Dropdown 
                  onFilterChange={function(e) {
                    _store.activeFilter = e.currentTarget.value;
                    console.log(_store); // in real life, some action would be dispatched here
                  }}
                  filterOptions={this.props.filterOptions}
                  value={this.props.activeFilter}
                  />
              </div>
            </div>
          );
      }
    });
    
    const ItemList = React.createClass({
      render: function() {
        return (
          <div>
            {this.props.items.map(function(item) {
              return <div key={item.id}>{item.id}: {item.label}</div>;
            })}
          </div>
        );
      }
    });
    
    const Dropdown = React.createClass({
        getInitialState: function() {
        return {
            isOpen: false
        };
      },
    
      render: function() {
        return (
            <div>
                <select 
                className="hidden-select" 
              onChange={this.props.onFilterChange}
              value={this.props.value}>
                {this.props.filterOptions.map(function(option) {
                return <option value={option.key} key={option.key}>{option.label}</option>
              })}
            </select>
    
            <div className={'custom-select' + (this.state.isOpen ? ' open' : '')} onClick={this.onClick}>
                <div className="selected-value">{this.props.activeFilter}</div>
              {this.props.filterOptions.map(function(option) {
                return <div data-value={option.key} key={option.key}>{option.label}</div>
              })}
            </div>
          </div>
        );
      },
    
      onClick: function(e) {
        this.setState({
            isOpen: !this.state.isOpen
        });
      }
    });
    
    ReactDOM.render(
      <App 
        listItems={getFilteredItems(_store.items, _store.activeFilter)} 
        filterOptions={_store.possibleFilters}
        activeFilter={_store.activeFilter}
        />,
      document.getElementById('root')
    );
    
  • 0

    道具是在渲染时传递到组件的值,对象或数组 . 这些道具通常是需要的 Value 在组件内创建UI,设置某些默认功能或用于填充字段 . 道具也可以以父子组件传递的函数的形式出现,子组件可以调用它们 .

    状态在组件(子级或父级)内进行管理 .

    这是我发现支持这个的定义:

  • 0

    这是我目前关于国家与道具之间解释的观点

    • State就像是组件中的局部变量 . 您可以使用set state来操纵state的值 . 然后,您可以将state的值传递给子组件 .

    • 道具是精确定位在redux商店内的值,这实际上来自于源自reducer的状态 . 您的组件应连接到redux以从props获取值 . 您还可以将道具值传递给子组件

  • 0

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

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

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

    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 });
    }
    
  • 1

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

    因此, state 仅限于您当前的组件,但 props 可以传递给您希望的任何组件...您可以将当前组件的 state 作为 prop 传递给其他组件...

    同样在React我们有 stateless components 只有道具而不是内部状态......

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

    Parent (state-full组件):

    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>
        );
      }
    }
    

    Child (无状态组件):

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

    简而言之 .

    使用setState方法[mutable]无法更改道具值[immutable]状态值

  • 2

    React Components使用state来读取/写入可以更改/变异的内部变量,例如:

    this.setState({name: 'Lila'})
    

    React props是一个特殊的对象,它允许程序员从Parent Component获取变量和方法到Child Component .

    它就像一扇窗户和房子的门 . 道具也是不可变的子组件无法更改/更新它们 .

    当父组件更改道具时,有几种方法可以帮助监听 .

  • 0

    您有一些数据正由应用程序中的某个用户输入 .

    • 输入数据的组件应该在 state 中包含此数据,因为它需要在数据输入期间操作和更改它

    • 应用程序中的任何其他位置,数据应作为 props 传递给所有其他组件

    所以道具正在改变,但它们在'source'处被改变,然后从那里简单地流下来 . 所以道具是不可变的 in the context of the component receiving them .

    例如 . 用户编辑供应商列表的参考数据屏幕将在状态中管理此状态,然后该操作会导致更新的数据保存在ReferenceDataState中,该数据可能比AppState低一级,然后此供应商列表将作为道具传递给所有需要使用它的组件 .

相关问题