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

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

文章后面说:

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

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


当前回答

用户在应用程序的某个地方输入了一些数据。

在其中输入数据的组件应该在其状态中拥有该数据,因为它需要在数据输入期间操作和更改它 在应用程序的其他任何地方,数据都应该作为道具传递给所有其他组件

所以,是的,道具是在变化的,但它们是从“源头”改变的,然后简单地从那里向下流动。所以道具在接收它们的组件的上下文中是不可变的。

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

其他回答

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>

Props:表示“只读”数据,是不可变的,引用父组件的属性。

状态:表示可变数据,它最终会影响页面上呈现的内容,并由组件本身内部管理,通常会由于用户输入而不断更改。

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

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

父类的childsName的状态值变成子类的this.props.name。从子进程的角度来看,名称道具是不可变的。如果它需要改变,父进程只需要改变它的内部状态:

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

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

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

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

Const元素=;

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

状态:状态只能在组件中访问。为了跟踪组件中的数据,我们使用状态。我们可以通过setState来改变状态。如果我们需要将state传递给child,我们必须将它作为props传递。

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