Javascript 这个错误意味着什么?渲染方法应该是道具和状态的纯函数

Javascript 这个错误意味着什么?渲染方法应该是道具和状态的纯函数,javascript,reactjs,Javascript,Reactjs,我对React是个新手,犯了这个错误 由于此方法而发生错误: deleteItem = (index) => { this.state.items.splice(index, 1), this.setState({ items: this.state.items }) } 我还使用@babel/plugin建议类属性 如果我将按钮onClick事件更改为: onClick={this.deleteItem.bind(inde

我对React是个新手,犯了这个错误

由于此方法而发生错误:

   deleteItem = (index) => {
    this.state.items.splice(index, 1),
    this.setState({
        items: this.state.items
    })
    }
我还使用@babel/plugin建议类属性

如果我将按钮onClick事件更改为:

     onClick={this.deleteItem.bind(index)}
它一开始工作得很好,我不知道为什么

整个代码示例

import React from 'react';

export default class extends React.Component{
    constructor(props) {
    super(props)
    this.state = {
        items: [1, 2, 3, 4, 5]
    };
};
addItem = () => {
    this.state.items.push('added');
    this.setState({
        items: this.state.items
    });
}
deleteItem = (index) => {
    this.state.items.splice(index, 1),
    this.setState({
        items: this.state.items
    })
}
render(){
    const list = this.state.items.map((item, index) => {
        return <li key={index}>{item}
        <button onClick={this.deleteItem(index)}>Remove</button>
        </li>
    });
    return (
        <div>
            <ul>
                {list}
            </ul>
            <button onClick={this.addItem}>Add</button>
        </div>
    )
}
}
从“React”导入React;
导出默认类扩展React.Component{
建造师(道具){
超级(道具)
此.state={
项目:[1,2,3,4,5]
};
};
附加项=()=>{
this.state.items.push('added');
这是我的国家({
项目:this.state.items
});
}
deleteItem=(索引)=>{
本.状态.项目.拼接(索引,1),
这是我的国家({
项目:this.state.items
})
}
render(){
const list=this.state.items.map((项目,索引)=>{
return
  • {item} 去除
  • }); 返回(
      {list}
    添加 ) } }
    如何解决此问题?

    请按照:

    切勿直接对this.state进行变异,因为之后调用setState()可能会替换您所做的变异。将this.state视为不可变的

    您正在直接改变
    状态
    ,不要这样做。在
    setState()
    方法中传递一个新的状态对象

     deleteItem = (index) => {
        const newItems = this.state.items.filter((ele, idx) => idx != index),
        this.setState({
            items: newItems
        })
     }
    
    或者您可以使用
    Array.prototype.slice()
    函数,该函数不会修改原始数组,因为它会在给定范围内获取其副本,并在新数组中返回:

    deleteItem = (index) => {
        const newItems = [...s.slice(0, index), ...s.slice(index + 1)],
        this.setState({
            items: newItems
        })
     }
    
    此外,
    上下文未在您的
    onClick
    处理程序中设置,请使用箭头函数
    ()=>
    捕获以下词法:

    onClick={() => this.deleteItem(index)}
    
    这是必要的,因为
    this
    指向当前执行上下文,如果不将
    this
    绑定到词法
    this
    ,并且调用回调时,
    this
    将不再引用组件实例

    另外,如果您立即调用
    deleteItem(index)
    ,处理程序将指向
    undefined
    ,而不是
    deleteItem
    引用,因为
    deleteItem(index)
    返回
    undefined

    您还需要修改
    addItem()
    方法,在该方法中,您应该从添加的元素中形成一个新数组:

    addItem = () => {
        this.setState({
            items: this.state.items.concat('added')
        });
    }
    

    问题是,您直接改变了您的状态,请使用
    filter

    deleteItem = (index) => {
      this.setState(state => ({
        items: state.items.filter((item, i) => index !== i)
      }))
    }
    
    我最近写了一篇关于使用React时的这些和其他问题的文章

    同时查看渲染代码,当您执行
    Remove
    时,它将立即执行
    deleteItem
    ,并将结果传递给
    onClick
    ,但是
    onClick
    需要一个函数。您需要做的是将其包装到函数中:

    <button onClick={() => this.deleteItem(index)}>Remove</button>
    
    this.deleteItem(index)}>Remove
    
    我们不能直接改变状态

    而不是

    addItem=()=>{
    this.state.items.push('added');
    这是我的国家({
    项目:this.state.items
    });
    
    }
    错误消息指的是函数式编程中的一个常见概念-纯函数-,它可以帮助您编写更少的错误代码。纯函数没有副作用,因为它们不会给变量分配新值,也不会改变应用程序的状态。纯函数的一个著名例子是返回参数的平方根。你可以在脑海中运行一个测试:你能多次调用这个函数并得到相同的结果吗?如果它是纯函数,多次调用它不会改变结果


    在您的示例中,应该可以多次呈现相同的内容,而不会产生任何副作用。呈现内容时不应添加或删除任何项目。如果你想让这个纯函数(render)返回不同的结果,你必须用不同的参数来调用它,这些参数是props和state。

    Try
    onClick={()=>this.deleteItem(index)}
    OMG,它可以工作。但您能解释一下原因吗?您将立即调用this.deleteItem并将该函数的返回值(未定义)传递给onClick处理程序,而不是传递将在单击事件时调用deleteItem的函数