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

时间:2017-08-31 05:48:54

标签: javascript reactjs react-native react-router

我哪里出错了?我一直在关注一个教程,但它总是给我这个错误。 TypeError: Cannot read property 'map' of undefined。什么会导致道具变得不确定。 这是我的代码:

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>
    );
    }
}

并始终指向var items = this.props.items.map((item, index) => ...。我不认为this教程有错误。我还是React的新人。

1 个答案:

答案 0 :(得分:1)

教程没有问题,但你遗漏了一部分, 检查最后一行:

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

todoItems传递给道具中的组件,因此this.props.todoItems将具有初始数据,但在您的情况下,您将导出组件并将其呈现在其他位置而不将数据传递给{{1 } {} TodoAppthis.props.todoItems的原因。

由于您在同一文件中定义数据,因此请直接使用本地数据。

像这样写:

undefined

其他解决方案:

不是将数据定义到此文件中,而是将其定义为导入TodoApp并进行渲染的位置,并从该位置传递数据。

像这样:

<TodoList items={todoItems} ....

<强>更新

使用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')); ,请查看此答案以获取更多详细信息:React vs ReactDOM?