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

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

文章后面说:

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

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


当前回答

主要的区别是状态只能在组件内部处理,而道具则在组件外部处理。如果我们从外部获取数据并进行处理,在这种情况下,我们应该使用状态。

其他回答

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

State就像组件中的局部变量。你可以操纵 使用set state获取state的值。然后可以传递state的值 例如,您的子组件。 Props是位于redux存储中的值 来源于来源于减速器的状态。您的组件 应该连接到redux从道具中获取值。你也可以通过 你的props值给你的子组件

Basically, props and state are two ways the component can know what and how to render. Which part of the application state belongs to state and which to some top-level store, is more related to your app design, than to how React works. The simplest way to decide, IMO, is to think, whether this particular piece of data is useful for application as a whole, or it's some local information. Also, it's important to not duplicate state, so if some piece of data can be calculated from props - it should calculated from props.

For example, let's say you have some dropdown control (which wraps standart HTML select for custom styling), which can a) select some value from list, and b) be opened or closed (i.e., the options list displayed or hidden). Now, let's say your app displays a list of items of some sort and your dropdown controls filter for list entries. Then, it would be best to pass active filter value as a prop, and keep opened/closed state local. Also, to make it functional, you would pass an onChange handler from parent component, which would be called inside dropdown element and send updated information (new selected filter) to the store immediately. On the other hand, opened/closed state can be kept inside dropdown component, because the rest of the application doesn't really care if the control is opened, until user actually changes it value.

下面的代码是不完全工作,它需要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')
);

简单地说:

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

react中“state”和“props”的区别。

React根据状态控制和渲染DOM。有两种类型的组件状态:props是组件之间传输的状态,state是组件的内部状态。Props用于将数据从父组件传输到子组件。组件在内部也有自己的状态:只能在组件内部修改的状态。

一般来说,某个组件的状态可以是子组件的道具,道具会传递给子组件,这是在父组件的呈现方法中声明的

状态:

状态是可变的。 状态与单个组件相关联,不能被其他组件使用。 在组件挂载时初始化状态。 状态用于呈现组件内的动态更改。

道具:

道具是不可变的。 您可以在组件之间传递道具。 道具主要用于组件之间的通信。你可以直接从父母传递给孩子。用于从孩子传递给父母 你需要使用提升状态的概念。

类Parent扩展React。组件{ 呈现() { 回报( < div > <孩子的名字= {"ron"}/> . < / div > ); } } 子类扩展React。组件{ { 呈现(){ 回报( < div > {this.props.name} < / div > ); } }