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

2020/09/23 19:41 · javascript ·  · 0评论

我正在观看有关React的Pluralsight课程,并且讲师说不应更改道具。我现在正在阅读有关道具与状态的文章(uberVU / react-guide),它说

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

文章稍后会说:

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

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

道具与状态有关。一个组件的状态通常会成为子组件的道具。道具将作为第二个参数传递给父对象的render方法中的子对象,React.createElement()或者,如果您使用的是JSX,则是更熟悉的标签属性。

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

父项的状态值childsName成为子项的状态值this.props.name从孩子的角度来看,prop这个名字是一成不变的。如果需要更改,则父级只需更改其内部状态即可:

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

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

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

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

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

对于亲子交流,只需传递道具即可。

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

使用道具将数据和事件处理程序传递到您的子组件。

这些列表应该有助于指导您在组件中使用数据。

道具

  • 是一成不变的

    • 让React进行快速参考检查
  • 用于从视图控制器向下传递数据

    • 您的顶级组件
  • 有更好的表现

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

  • 应该在您的视图控制器中进行管理

    • 您的顶级组件
  • 易变
  • 性能较差
  • 不应从子组件访问

    • 用道具传下来

要在没有父子关系的两个组件之间进行通信,可以设置自己的全局事件系统。订阅componentDidMount()中的事件,取消订阅componentWillUnmount()中的事件,并在收到事件时调用setState()。助焊剂模式是解决此问题的一种可能方法。- https://facebook.github.io/react/tips/communicate-between-components.html

哪些组件应具有状态?

您的大多数组件都应该简单地从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

通过将其与Plain JS函数相关联,可以最好地理解它。

简单的说,

状态是组件的本地状态,无法在组件外部访问和修改。它等效于函数中的局部变量。

普通JS功能

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

反应组件

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

另一方面,通过赋予组件以道具形式从其父组件接收数据的能力,道具使组件可重用。它们等效于功能参数。

普通JS功能

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

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

反应组件

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与Props的解释

我最喜欢的道具vs状态摘要在这里:react-guide那些家伙的大礼帽。以下是该页面的编辑版本:


道具与状态

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


道具

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

状态是一个数据结构,在安装组件时,该结构以默认值开头。它可能会随时间变化,这主要是由于用户事件造成的。

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

改变道具和状态

                                                   道具状态
    可以从父组件获取初始值吗?是的是的
    可以由父组件更改吗?是否
    可以在组件内部设置默认值吗?*是是
    可以在组件内部更改吗?不可以
    可以为子组件设置初始值吗?是的是的
    可以更改子组件吗?是否
  • 请注意,从父级接收到的prop和state初始值都将覆盖Component内部定义的默认值。

这个组件应该有状态吗?

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

组件类型

无状态组件仅道具,无状态。除了render()函数外,没有什么其他事情了。他们的逻辑围绕着他们收到的道具。这使得它们非常易于遵循和测试。

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

资料来源

道具(“属性”的缩写)和状态都是纯JavaScript对象。两者都拥有影响渲染输出的信息,但是它们在一个重要方面有所不同:道具被传递到组件(类似于函数参数),而状态在组件内进行管理(类似于函数中声明的变量)。

所以,简单地状态仅限于当前的组件,但道具可以通到你希望的任何组件...您可以通过状态的电流分量,作为道具的其它组件...

同样在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>
    );
  }
}

子级(无状态组件):

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

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

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

render(<A message=”hello />,document.getElementById(“root”));


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

状态VS道具

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

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

两个状态道具中发生反应被用来控制数据到一个组件,一般道具由父设置并传递到子组件和它们固定整个组件。对于将要更改的数据,我们必须使用状态。而且道具是不可变的,而状态是可变的,如果要更改道具,可以从父组件执行,然后将其传递给子组件。

正如我在与之合作时所学到的。

  • 组件使用props 从外部环境(即,另一个组件(纯,功能或类)或通用类javascript /打字稿代码)中获取数据

  • 状态用于管理组件的内部环境,意味着数据组件内部发生更改

道具:道具只是组件的属性,而react组件只是一个javascript函数。

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

const element =;

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

状态:状态只能在Component中访问。为了跟踪组件中的数据,我们使用状态。我们可以通过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>);
  }
}

州:

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

道具:

  1. 道具是一成不变的。
  2. 您可以在组件之间传递道具。
  3. 道具通常用于组件之间的通信。您可以直接从父级传递到子级。为了从孩子传给父母,您需要使用提升状态的概念。
class Parent extends React.Component{
  render()
  {
     return(
        <div>
            <Child name = {"ron"}/>
        </div>
      );
  }
}

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

基本上,道具和状态是组件知道什么以及如何渲染的两种方式。应用程序状态的哪一部分属于状态,哪一部分属于某个顶级存储,与您的应用程序设计有关,而不是与React的工作方式有关。决定IMO的最简单方法就是思考,这块特定的数据对于整个应用程序是否有用,还是某些本地信息。另外,不要复制状态也很重要,因此,如果可以通过props计算某些数据-应该从props计算数据。

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

以下代码无法完全正常运行,它需要CSS并处理下拉click / blur / change事件,但我想尽量减少示例。希望它有助于理解差异。

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

状态是处理组件所拥有信息的反应方式。

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

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

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

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

那么,有什么和我们在OO编程中总是只使用对象属性有什么不同?通常,您所处状态中的信息并不是静态的,它会随着时间的推移而变化,您的视图将需要更新以反映此变化。State以简单的方式提供此功能。

状态是无法改变的!我对此没有施加足够的压力。这是什么意思?这意味着您永远不要做这样的事情。

 state.key2 = newValue;

正确的做法是:

this.setState({ key2: newValue });

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

检查react docs以获取更多扩展说明:https :
//facebook.github.io/react/docs/state-and-lifecycle.html

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

道具 -这是一种特殊的属性,它本质上是不可变的,在按价值从父级传递给子级的情况下使用。道具只是组件之间的交流渠道,总是从顶部(父级)移动到buttom(子级)。

以下是结合状态和道具的完整示例:-

<!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>

道具只是属性的简写。道具是组件之间如何对话的方式。如果您完全熟悉React,那么您应该知道道具从父组件向下流动。

在某些情况下,您可以具有默认道具,即使父组件不向下传递道具,也可以设置道具。

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

所以我们很高兴。组件从父级接收数据。全部整理好吗?

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

好吧,这就是为什么我们有状态。

道具不应该改变,所以状态会提高。通常,组件没有状态,因此称为无状态。使用状态的组件称为有状态。随意在聚会上丢下这个小花招,看着别人渐渐远离您。

因此使用状态,以便组件可以跟踪其执行的任何渲染之间的信息。当您设置状态时,它会更新状态对象,然后重新渲染组件。这是超酷的,因为这意味着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);
 }
}

摘要

道具和国家做类似的事情,但使用方式不同。您的大多数组件可能都是无状态的。

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

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

简而言之。

道具值无法更改[不可变]

状态值可以使用setState方法[mutable]进行更改

通常,一个组件(父组件)的状态是子组件的道具。

  1. 状态位于组件从父级传递到子级的组件内。
  2. 道具通常是不可变的。

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

在上面的代码中,我们有一个父类(父类),其父类的名称作为状态被传递给子组件(子类)作为道具,子组件使用{this.props.name}进行渲染。

在React中,状态会存储数据以及道具。与后者的不同之处在于可以通过不同的更改来修改存储的数据。这些只不过是用平面JavaScript编写的对象,因此它们可以包含数据或代码,代表您要建模的信息。如果您需要更多的细节,建议你看这些出版物
中使用做出反应的国家
道具的用途作出反应

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

  1. 状态就像组件内部的局部变量。您可以使用set state来操纵state的值。然后,您可以例如将state的值传递给子组件。

  2. 道具是确切位于您的redux存储内的值,它实际上来自于reducer产生的状态。您的组件应连接到redux以从props获取值。您还可以将props值传递给子组件

您有一些数据正在由用户在应用程序中的某处输入。

  1. 输入数据的组件应具有此数据的状态,因为它需要在数据输入期间进行操作和更改

  2. 在应用程序的其他任何地方,数据都应作为道具传递给所有其他组件

所以是的,道具正在发生变化,但是它们在“源”处发生了变化,然后将仅从那里流下来。因此,道具在组件接收它们的上下文中是不可变

例如,参考数据屏幕,用户在其中编辑供应商列表将在状态下进行管理,然后执行一个操作,使更新的数据保存在ReferenceDataState中,该数据可能位于AppState的下一级,然后此供应商列表将作为道具传递到需要使用它的所有组件。

  • 道具 ---你不能改变它的价值。
  • 状态 ---您可以在代码中更改其值,但是在进行渲染时它将处于活动状态。

反应中“状态”和“道具”之间存在一些差异。

React根据状态控制和呈现DOM。组件状态有两种类型:props是在组件之间转移的状态,而state是组件的内部状态。道具用于从父组件到子组件的数据传输。组件内部也有自己的状态:状态只能在组件内部进行修改。

通常,某些组件的状态可能是子组件的props,props将传递给子组件,这在父组件的呈现方法中声明

道具

  • 道具用于在子组件中传递数据

  • 道具更改组件(子组件)外部的值

  • 状态在类组件中的使用

  • 状态更改组件内部的值

  • 如果呈现页面,则调用setState来更新DOM(更新页面值)

国家在反应中起着重要作用

在回答有关道具是不可变的最初问题时,就子组件而言,据说道具是不可变的,但在父组件中是可变的。

React组件使用状态来读/写可以通过以下方式更改/更改的内部变量:

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

React道具是一个特殊的对象,它允许程序员将变量和方法从父组件获取到子组件中。

就像房子的窗户和门一样。道具也是不可变的,子组件不能更改/更新它们。

有几种方法可以帮助侦听父组件更改道具时的情况。

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

状态是您的数据,是可变的,您可以使用它做任何您需要的事情,道具是只读数据,通常当您传递道具时,您已经使用了数据,并且需要子组件来呈现它,或者您的道具是一个道具。你调用它执行任务的功能

状态是真理的起源,您的数据生活在这里。
您可以说国家通过道具表现出来。

为组件提供道具可以使您的UI与数据保持同步。组件实际上只是一个返回标记的函数。

给定相同的道具(用于显示的数据),它将始终产生相同的标记

因此,道具就像将数据从原点传送到功能组件的管道一样。

道具:表示“只读”数据,该数据是不可变的,是指来自父级组件的属性。

状态:代表可变数据,最终会影响页面上呈现的内容以及由组件本身在内部进行管理的内容,并且通常由于用户输入而导致超时变化。

主要区别在于,状态是组件的私有状态,并且仅当props是子组件的静态值和键时才可以在该组件内更改,而子组件是通过父组件传递的,而在子组件内部则不能更改

本文地址:http://javascript.askforanswer.com/reactzhongdestatehepropsyoushenmequbie.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!