无法渲染todoItems

时间:2018-05-09 01:01:49

标签: reactjs

我正在使用React创建Todo App

以下是我的容器文件:App.js

import React, { Component } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';

class App extends Component{
  state ={
    todoItem: []
  }
  addTodoHanlder = event => {
    let todosValue = event.target.value;
    let newTodos = this.state.todoItem.push(todosValue)
    this.setState({
      todoItem: newTodos
    })
  }


render(){
  return(
    <div>
      <input type="text" />
      <button onClick={this.addTodoHanlder}>AddTodo</button>
      <Hello todos={this.state.todoItem}/>
    </div>
  )
}
}
render(<App />, document.getElementById('root'));

以下是我的Hello组件:

import React from 'react';

const hello = (props) => {
  return(
    <div>
      <ul>
        {props.todos.map(todo => {
          return (
            <li>{todo}</li>
          )
        })}
      </ul>
    </div>
  )
}

export default hello;

我收到此错误:TypeError props.todos.map不是函数

有人可以帮我解决这个问题并解释究竟发生了什么,以及如何渲染我的待办事项?

2 个答案:

答案 0 :(得分:1)

问题是你如何修改数组。 push的返回值是您正在推送的值。因此,当您尝试追加到数组时,您将存储附加值,而不是新数组。

let newTodos = this.state.todoItem.push(todosValue) # newTodos = todosValue

我的建议是将状态视为不可变状态,并创建一个可以追加的新对象。

let newTodos = this.state.todoItem.slice();
newTodos.push(todosValue);
this.setState({
  todoItem: newTodos
});

如果您使用的是ES6,也可以使用ES6点差运算符。

let todosValue = event.target.value;
this.setState({
  todoItem: [...this.state.todoItem, todosValue]
})

您在渲染待办事项时也会遇到问题。 event.target是您点击的按钮。您需要从输入中提取以存储待办事项文本。

答案 1 :(得分:0)

嗨,这非常有帮助。我使用了你建议的ES6概念,但我做了一些修改才能完成这项工作。 我使用另一个变量来存储我的输入文本,然后在每次更改状态后清除它。

更新了App.js:

import React, { Component } from "react";
import { render } from "react-dom";
import Hello from "./Hello";

class App extends Component {
  state = {
    todoItem: [],
    **todoText: ""**
  };
  addTodoHanlder = event => {
    let todoValue = this.state.todoText;
    this.setState({
      todoItem: [...this.state.todoItem, todoValue]
    });
    this.clearTodoText();
    **todoValue = "";**
  };

  **clearTodoText() {
    this.setState({ todoText: "" });
  }

  handleChange = event => {
    this.setState({ todoText: event.target.value });
  };**

  render() {
    return (
      <div>
        <input
          type="text"
          placeholder="Enter Todo"
          **value={this.state.todoText}
          onChange={this.handleChange}**
        />
        <button onClick={this.addTodoHanlder}>AddTodo</button>
        <Hello todos={this.state.todoItem} />
      </div>
    );
  }
}
render(<App />, document.getElementById("root"));

突出显示所做的更改。