繁体   English   中英

与状态列表反应,如何设置新状态?

[英]React with lists in state, how to set new state?

我遇到了更新部分状态的问题,该部分状态是已传递给组件子级的列表。

我将一个列表传递给一个孩子,但随后却无法更新该列表并使孩子反映新状态。

<ItemsClass items={this.state.items1} />

当我更改this.state.items1的值时,组件不会使用新值进行渲染。

this.setState({items1: []}); // this has no effect

但是,如果更改现有数组(而不是将其替换为新的空数组),则该组件将按照我的意愿进行渲染;

this.setState(state => { clearArray(state.items1); return state; });

这意味着状态更新功能不是纯粹的,React应该是这样。

HTML;

<div id='app'></div>

js;

class ItemsClass extends React.Component {
  constructor(props){
    super(props);

    this.state = {items: props.items};
  }

  render() {
    var items = this.state.items.map(it => <div key={it.id}>{it.text}</div>);
    return(
      <div>{items}</div>
    );
  }
}

function ItemsFunction(props) {
  var items = props.items.map(it => <div key={it.id}>{it.text}</div>);
    return(
      <div>{items}</div>
    );
}

class App extends React.Component {
  constructor(props){
    super(props);
    var items = [{id:1, text: 'item 1'}, {id: 2, text: 'item 2'}];

    this.state = {
      items1: items.slice(),
      items2: items.slice(),
      items3: items.slice()
    };
    this.clearLists = this.clearLists.bind(this);
  }

  clearLists() {
    // for items1 and items2, clear the lists by assigning new empty arrays (pure).
    this.setState({items1: [], items2: []});

    // for items3, change the already existing array (non-pure).
    this.setState(state => {
      while (state.items3.length) {
        state.items3.pop();
      }
    })
  }

  render() {
    return (
      <div>
        <button onClick={this.clearLists}>Clear all lists</button>
        <h2>Items rendered by class, set list to new empty array</h2>
        <ItemsClass items={this.state.items1} />
        <h2>Items rendered by class, empty the already existing array</h2>
        <ItemsClass items={this.state.items3} />
        <h2>Items rendered by function</h2>
        <ItemsFunction items={this.state.items2} />
      </div>
      );
  }
}

ReactDOM.render(<App />, document.getElementById('app'));

Codepen上尝试一下。

看来, ItemsClass虽然它与创建甚至不更新<ItemsClass items={this.state.items1}/>this.state.items1父的变化。

这是预期的行为吗? 如何从父项更新ItemsClass子项中的状态? 我想念什么吗? 这种行为似乎很容易出错,因为很容易假定子代应遵循新状态,即创建子代时传入的方式。

您将在组件初始化时将ItemsClass的道具复制到状态中-道具更改时不会重置状态,因此不会显示组件的更新。 引用文档

当心这种模式,因为状态不会随着任何道具更新而保持最新。 您通常不希望将道具同步到状态,而要提升状态。

如果在更改道具时您的组件必须执行某些操作,则可以使用componentWillReceieveProps生命周期挂钩来执行此操作(请注意,当组件最初安装时,它不会运行,仅在后续的道具更新时才运行)。

就是说,您在这里复制道具的理由是零的(并且坦白地说,通常没有很好的理由这样做)-就像在使用ItemsFunction ,直接使用道具就可以了,一切都会保持同步:

class ItemsClass extends React.Component {
  render() {
    var items = this.props.items.map(it => <div key={it.id}>{it.text}</div>);
    return(
      <div>{items}</div>
    );
  }
}

这是Codepen的工作版本: http ://codepen.io/anon/pen/JNzBPV

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM