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

时间:2017-03-02 02:04:27

标签: javascript reactjs

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

我想从子组件中更改父级的items数组状态。我试图将addItem函数作为prop传递给children组件,在输入时,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 个答案:

答案 0 :(得分:1)

我可以帮助@AndrewLi解释。看看这个article。它解释了为什么需要在React中绑定函数。快速解释归结为scope

addItem函数中的this是什么?它可能不是你所期望的那样。因此,您必须将相应的this绑定到函数,以便您可以按照预期的方式使用它,例如调用this.state.items。如果this不是您期望的this,则会产生不良后果。

所以你可以这样做:

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

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

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

两者都给你相同的结果

答案 1 :(得分:0)

您可以将函数作为回调而不是“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});
    }
}

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