开发者问题收集

ReactJS-无法读取未定义的属性“items”

2017-03-02
7113

我正在学习 ReactJS,但我偶然发现了这个我无法弄清楚的错误。

我想从其子组件更改父组件的 items 数组状态。我尝试将 addItem 函数作为 prop 传递给 children 组件,在输入时,子组件调用此函数并传入输入值。

当我尝试在 addItem 方法中 console.log(this.state.items) 时,出现此错误。

Uncaught TypeError: Cannot read property 'items' of undefined

App.js

class App extends Component {
    constructor() {
        super();
        this.state = {
            items: []
        };
    }

    render() {
        return (
            <div className="App">
                <p>Todo List</p>
                <AddItemBox addNewItem={this.addItem}/>
                <ItemsList items={this.state.items}/>
            </div>
        );
    }

    addItem(item) {
        var listItems = this.state.items;
        listItems.push(item);
        this.setState({items: listItems});
    }
}

子组件: AddItemBox.js

class AddItemBox extends Component {
    constructor(props) {
        super(props);
        this.state = {
            item: '' // input value
        };
    }

    render() {
        return (
            <div className='AddItemBox'>
                <input type='text' placeholder='add item' onChange={e => {
                this.onInputChange(e.target.value)
            }} onKeyPress={e => {
                if (e.key === 'Enter') {
                    this.onInputEnter(e.target.value)
                }
            }}/>
            </div>
        );
    }

    onInputChange(item) {
        this.setState({item});
    }

    onInputEnter(item) {
        // Now add it to the 'items' array state
        this.props.addNewItem(item);
        this.setState({item: ''});
    }
}
2个回答

我可以帮助 @AndrewLi 解释。查看此 文章 。它解释了为什么需要在 React 中绑定函数。简单的解释归结为 scope

addItem 函数中的 this 是什么?它可能不是您期望的那样。因此,您必须将适当的 this 绑定到该函数,以便您可以按照您想要的方式使用它,例如调用 this.state.items 。如果 this 不是您期望的 this ,您将得到不理想的结果。

因此,您可以这样做:

constructor(props) {
        super(props);
        this.state = {
            item: '' // input value
        };
        
        this.addItem = this.addItem.bind(this)
    }

或者,您可以使用 es6 并执行以下操作:

addItem = (item) => {
    var listItems = this.state.items;
    listItems.push(item);
    this.setState({items: listItems});
}

两者都会给出相同的结果

Turnipdabeets
2017-03-02

您可以将函数作为回调传递,而不是在“AddItemBox”组件中传递引用,如

class App extends Component {
    constructor() {
        super();
        this.state = {
            items: []
        };
        this.addItem = this.addItem.bind(this);
    }

    render() {
        return (
            <div className="App">
                <p>Todo List</p>
                <AddItemBox addNewItem={(item) => this.addItem(item)}/>
                <ItemsList items={this.state.items}/>
            </div>
        );
    }

    addItem(item) {
        var listItems = this.state.items;
        listItems.push(item);
        this.setState({items: listItems});
    }
}

您还需要在构造函数中绑定该函数。

pritesh
2017-03-02