Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在状态中对列表作出反应,如何设置新状态?_Javascript_Reactjs - Fatal编程技术网

Javascript 在状态中对列表作出反应,如何设置新状态?

Javascript 在状态中对列表作出反应,如何设置新状态?,javascript,reactjs,Javascript,Reactjs,我在更新部分状态时遇到了一个问题,该状态是传递给组件子级的列表 我将一个列表传递给一个孩子,但随后很难更新该列表并让孩子反映新的状态 <ItemsClass items={this.state.items1} /> 但是,如果我更改了已经存在的数组(而不是将其替换为新的空数组),则该组件将按照我的意愿进行渲染 this.setState(state => { clearArray(state.items1); return state; }); 这意味着状态更新函数不是纯粹

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

我将一个列表传递给一个孩子,但随后很难更新该列表并让孩子反映新的状态

<ItemsClass items={this.state.items1} />
但是,如果我更改了已经存在的数组(而不是将其替换为新的空数组),则该组件将按照我的意愿进行渲染

this.setState(state => { clearArray(state.items1); return state; });
这意味着状态更新函数不是纯粹的,它应该是什么样的状态

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'));
class ItemsClass扩展了React.Component{
建造师(道具){
超级(道具);
this.state={items:props.items};
}
render(){
var items=this.state.items.map(it=>{it.text});
返回(
{items}
);
}
}
功能项功能(道具){
var items=props.items.map(it=>{it.text});
返回(
{items}
);
}
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
var items=[{id:1,文本:'item 1'},{id:2,文本:'item 2'}];
此.state={
items1:items.slice(),
items2:items.slice(),
items3:items.slice()
};
this.clearLists=this.clearLists.bind(this);
}
清除列表(){
//对于items1和items2,通过分配新的空数组(pure)清除列表。
this.setState({items1:[],items2:[]});
//对于items3,更改已经存在的数组(非纯数组)。
this.setState(state=>{
while(state.items3.length){
state.items3.pop();
}
})
}
render(){
返回(
清除所有列表
按类呈现的项,将列表设置为新的空数组
按类呈现的项,清空已存在的数组
按函数呈现的项
);
}
}
ReactDOM.render(

即使父级中的
this.state.items1
创建了
项目类,但它似乎不会更新

这是预期的行为吗?如何从父级更新
ItemsClass
子级中的状态?
我遗漏了什么?这种行为似乎很容易出错,因为很容易假设子级应该遵循新状态,即创建子级时传递的方式。

您正在将
ItemsClass
的道具复制到组件初始化时的状态-在道具更改时不重置状态,因此无法显示组件的更新。要引用:

注意这种模式,因为状态不会随着任何道具更新而更新。您通常希望提升状态,而不是将道具同步到状态

如果您的组件在道具更改时必须执行某些操作,您可以使用lifecycle挂钩来执行(请注意,当组件最初装载时,它不会运行,仅在后续道具更新时运行)

这就是说,您没有理由在这里复制道具(老实说,一般来说很少有好的理由这样做)-只需直接使用道具,就像您在使用
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>
    );
  }
}
class ItemsClass扩展了React.Component{
render(){
var items=this.props.items.map(it=>{it.text});
返回(
{items}
);
}
}

这是您的代码笔的工作版本:

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

注意这种模式,因为状态不会随着任何道具更新而更新。您通常希望提升状态,而不是将道具同步到状态

如果您的组件在道具更改时必须执行某些操作,您可以使用lifecycle挂钩来执行(请注意,当组件最初装载时,它不会运行,仅在后续道具更新时运行)

这就是说,您没有理由在这里复制道具(老实说,一般来说很少有好的理由这样做)-只需直接使用道具,就像您在使用
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>
    );
  }
}
class ItemsClass扩展了React.Component{
render(){
var items=this.props.items.map(it=>{it.text});
返回(
{items}
);
}
}
以下是您的代码笔的工作版本: