javascript - 与状态列表进行 react ,如何设置新状态?

标签 javascript reactjs

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

我将列表传递给子项,但随后无法更新该列表并让子项反射(reflect)新状态;

<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 中的状态 child 来自 parent ? 我是不是错过了什么?这种行为似乎很容易出错,因为很容易假设子级应该遵循新状态,即创建子级时传入的方式。

最佳答案

您正在复制 ItemsClass 的 props进入组件初始化时的状态 - 当 props 更改时您不会重置状态,因此组件的更新不会显示。引用docs :

Beware of this pattern, as state won't be up-to-date with any props update. Instead of syncing props to state, you often want to lift the state up.

如果你的组件在 props 改变时必须做一些事情,你可以使用 componentWillReceieveProps生命周期 Hook 来执行此操作(请注意,它在组件最初安装时不会运行,仅在后续的 prop 更新时运行)。

也就是说,您在这里复制 Prop 的理由为零(老实说,一般来说很少有充分的理由这样做) - 只需直接使用 Prop ,就像您对 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

关于javascript - 与状态列表进行 react ,如何设置新状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44181690/

相关文章:

javascript - jQuery 数据表使用实时函数多次调用事件处理程序

php - Document.getElementById 在 Google map 信息窗口中不起作用

javascript - Appium selenium 字段中的明文

javascript - Redux thunk : how to await completion of an async action

javascript - 如何在 html 中使用纯 javascript 切换类

javascript - 如何找到子菜单的宽度扩展

javascript - 滚动时自动完成保持为 "FIXED"(所有浏览器)

javascript - 使用 React 组件分发 CSS

reactjs - 在 formik 组件之外处理 formik 表单

javascript - React State 没有按预期工作,有更好的方法吗?