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

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

文章后面说:

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

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


当前回答

在react中,我们通常使用模块来分离组件。有时分离的组件需要在它们内部共享数据。如果父组件有一些数据应该在子组件上共享,那么道具是解决方案。我们可以使用从父母到孩子的道具共享数据。Props是不可变的,这意味着您不能更改数据。

另一方面,状态用于跟踪数据中的任何变化。您可以将状态视为数据的存储和可以更新该数据的函数。状态是可变的。您可以在同一组件中使用setState函数更改状态

其他回答

状态是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

给出最简单的解释,补充上述评论:

根据React的官方文档,他们将“状态”视为

To “remember” things, components use state.

props可以理解为从父组件传递给子组件的变量。

如果你想在应用中记住一些东西,你会使用状态如果你想传递数据,你会使用道具。

让我给你另一个类比,假设你想把你脑子里的前25个自然数的序列相加。

1+2+3+4.....

从1开始,然后加2,现在是3,然后加到现在的总数(6),然后加4到现在的总数(6),所以新的总数是10。

当前的总和是程序的状态,假设您需要找到总和的平均值。你要把这个和代入一个方程,然后把这个和作为道具传下去。

希望这能说得通。

简单地说:

状态由组件自己管理。它是可重用的、组件私有的、可修改的。 道具从父母传递给孩子。它是一个单向流,子组件是只读的。父组件的状态可以作为道具传递给子组件。

state -这是一个特殊的可变属性,保存组件数据。它在Componet挂载时具有默认值。

props -这是一个特殊的属性,本质上是不可变的,用于从父到子的值传递。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>

道具只是属性的简写。道具是组件之间相互交流的方式。如果你熟悉React,那么你应该知道道具是从父组件向下流动的。

还有一种情况是,你可以有默认的道具,这样即使父组件没有传递道具,道具也会被设置。

这就是为什么人们认为React具有单向数据流。这需要一些理解,我可能会在后面的博客中对此进行讨论,但现在只要记住:数据从父流向子。道具是不可变的(是指不变的)

所以我们很高兴。组件从父组件接收数据。都整理好了,对吧?

嗯,不完全是。当组件从父组件以外的对象接收数据时会发生什么?如果用户直接向组件输入数据呢?

这就是我们有状态的原因。

状态

道具不应该改变,所以状态上升。组件通常没有状态,因此被称为无状态。使用状态的组件称为有状态的。在聚会上随便说说你的小秘密,然后看着人们慢慢地离你而去。

所以使用状态是为了让组件可以在它所做的任何渲染之间跟踪信息。当你setState时,它更新状态对象,然后重新渲染组件。这非常酷,因为这意味着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);
 }
}

总结

道具和状态的作用类似,但使用方式不同。大多数组件可能是无状态的。

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

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