简体   繁体   English

ReactJS TypeError:无法读取未定义的属性“ map”

[英]ReactJS TypeError: Cannot read property 'map' of undefined

Where did I get wrong?. 我在哪里弄错了? I've been following a tutorial but it always gives me this error. 我一直在遵循一个教程,但它总是给我这个错误。 TypeError: Cannot read property 'map' of undefined . TypeError: Cannot read property 'map' of undefined and What would cause the prop to become undefined. 什么会导致道具变得不确定。 here's my code: 这是我的代码:

var todoItems = [];
todoItems.push({index: 1, value: "learn react", done: false});
todoItems.push({index: 2, value: "Go shopping", done: true});
todoItems.push({index: 3, value: "buy flowers", done: true});

class TodoList extends React.Component {
    render () {
        var items = this.props.items.map((item, index) => {
                return (
            <TodoListItem key={index} item={item} index={index} removeItem={this.props.removeItem} markTodoDone={this.props.markTodoDone} />
    );
    });
        return (
            <ul className="list-group"> {items} </ul>
    );
    }
}

class TodoListItem extends React.Component {
    constructor(props) {
        super(props);
        this.onClickClose = this.onClickClose.bind(this);
        this.onClickDone = this.onClickDone.bind(this);
    }
    onClickClose() {
        var index = parseInt(this.props.index);
        this.props.removeItem(index);
    }
    onClickDone() {
        var index = parseInt(this.props.index);
        this.props.markTodoDone(index);
    }
    render () {
        var todoClass = this.props.item.done ?
            "done" : "undone";
        return(
            <li className="list-group-item ">
            <div className={todoClass}>
            <span className="glyphicon glyphicon-ok icon" aria-hidden="true" onClick={this.onClickDone}></span>
        {this.props.item.value}
    <button type="button" className="close" onClick={this.onClickClose}>&times;</button>
        </div>
        </li>
    );
    }
}

class TodoForm extends React.Component {
    constructor(props) {
        super(props);
        this.onSubmit = this.onSubmit.bind(this);
    }
    componentDidMount() {
        this.refs.itemName.focus();
    }
    onSubmit(event) {
        event.preventDefault();
        var newItemValue = this.refs.itemName.value;

        if(newItemValue) {
            this.props.addItem({newItemValue});
            this.refs.form.reset();
        }
    }
    render () {
        return (
            <form ref="form" onSubmit={this.onSubmit} className="form-inline">
            <input type="text" ref="itemName" className="form-control" placeholder="add a new todo..."/>
            <button type="submit" className="btn btn-default">Add</button>
            </form>
    );
    }
}

class TodoHeader extends React.Component {
    render () {
        return <h1>Todo list</h1>;
    }
}

export default class TodoApp extends React.Component {
    constructor (props) {
        super(props);
        this.addItem = this.addItem.bind(this);
        this.removeItem = this.removeItem.bind(this);
        this.markTodoDone = this.markTodoDone.bind(this);
        this.state = {todoItems: todoItems};
    }
    addItem(todoItem) {
        todoItems.unshift({
            index: todoItems.length+1,
            value: todoItem.newItemValue,
            done: false
        });
        this.setState({todoItems: todoItems});
    }
    removeItem (itemIndex) {
        todoItems.splice(itemIndex, 1);
        this.setState({todoItems: todoItems});
    }
    markTodoDone(itemIndex) {
        var todo = todoItems[itemIndex];
        todoItems.splice(itemIndex, 1);
        todo.done = !todo.done;
        todo.done ? todoItems.push(todo) : todoItems.unshift(todo);
        this.setState({todoItems: todoItems});
    }
    render() {
        return (
            <div id="main">
            <TodoHeader />
            <TodoList items={this.props.initItems} removeItem={this.removeItem} markTodoDone={this.markTodoDone}/>
    <TodoForm addItem={this.addItem} />
    </div>
    );
    }
}

and it always points to the var items = this.props.items.map((item, index) => ... . I don't think this tutorial has an error. I'm still new in React. 它总是指向var items = this.props.items.map((item, index) => ...我不认为教程有错误,我还是React的新手。

There is no issue with tutorial, but you missed one part, Check the last line: 教程没有问题,但是您错过了一部分,请检查最后一行:

ReactDOM.render(<TodoApp initItems={todoItems}/>, ....);

There todoItems is passed into component in props so this.props.todoItems will have the initial data, but in your case you are exporting the component and rendering it somewhere else and not passing the data to TodoApp component that's why this.props.todoItems is undefined . 在道具todoItems传递到组件中,因此this.props.todoItems将具有初始数据,但是在您的情况下,您正在导出组件并将其呈现在其他位置,而不是将数据传递给TodoApp组件,这就是this.props.todoItemsundefined

Since you define the data in the same file, So use the local data directly. 由于您在同一文件中定义数据,因此请直接使用本地数据。

Write it like this: 像这样写:

<TodoList items={todoItems} ....

Other solution: 其他解决方案:

Instead of defining the data into this file define it where you are importing TodoApp and rendering it, and pass the data from that place it will work. 无需将数据定义到此文件中,而是在将TodoApp导入并呈现它的位置定义它,然后从该位置传递数据即可使用。

Like this: 像这样:

import TodoApp from '/path_to_todoapp/';

var todoItems = [];
todoItems.push({index: 1, value: "learn react", done: false});
todoItems.push({index: 2, value: "Go shopping", done: true});
todoItems.push({index: 3, value: "buy flowers", done: true});

ReactDOM.render(<TodoApp initItems={todoItems}/>, document.getElementById('app'));

Update: 更新:

Use ReactDOM.render , check this answer for more details: React vs ReactDOM? 使用ReactDOM.render ,检查此答案以获取更多详细信息: React vs ReactDOM?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM