首页 > 解决方案 > React Todo App 将类组件转换为功能组件时出现错误

问题描述

首先,提前感谢您的帮助。在制作 Todo App 时,我在功能组件中进行了添加和删除操作,但我无法制作其他组件。如果您能提供帮助,我会很高兴。

TodoItem.js:(我尝试了很多,但由于错误无法使其正常工作。)

class TodoItem extends Component {
  render() {
    const { id, title } = this.props.todo // I did not understand here what it does.

    return (
      <div>
        <p>
          <input
            type="checkbox"
            onChange={this.props.markComplete.bind(this, id)} // and here too
          />
          {""} {title}{" "}
          <button onClick={this.props.deleteTodo.bind(this, id)}>X </button>{" "}
        </p>{" "}
      </div>
    )
  }
}

Addtodo.js:(我将其转换为功能,但它没有列出我写的输入。)

const Addtodo = () => {
  const [title, setTitle] = useState("")

  const onSubmit = (e) => {  // I made a mistake here, I don't know why there is a problem.
    e.preventDefault()
    setTitle("")
  }

  const onChange = (e) => setTitle(e.target.value)

  return (
    <form onSubmit={onSubmit}>
      <input
        type="text"
        onChange={onChange}
        value={title}
        placeholder="Add todo"
      />
      <input type="Submit" value="Submit" className="btn" />
    </form>
  )
}

App.js 组件:(我能够使它们发挥作用。如果你能检查一下,我会很高兴。)

const App = () => {
  const [todos, setTodos] = useState([])

  useEffect(() => {
    axios
      .get("https://jsonplaceholder.typicode.com/todos")
      .then((res) => setTodos(res.data))
  }, [])

  const markComplete = (id) => {
    setTodos(
      todos.map((todo) => {
        if (todo.id === id) {
          todo.completed = !todo.completed
        }
        return todo
      })
    )
  }

  const deleteTodo = (id) => {
    axios
      .delete(`https://jsonplaceholder.typicode.com/todos/${id}`)
      .then((res) => setTodos([...todos.filter((todo) => todo.id !== id)]))
  }

  // Add Todo
  const Addtodo = (title) => {
    axios
      .post("https://jsonplaceholder.typicode.com/todos", {
        title,
        completed: false
      })
      .then((res) => setTodos([...todos, res.data]))
  }

  return (
    <div className="App">
      <div className="container"> 
        <Header />
        <AddTodo Addtodo={Addtodo} /> // I think I made a mistake here with the props.
        <Todo
          todos={todos}
          markComplete={markComplete}
          deleteTodo={deleteTodo}
        />{" "}
      </div>{" "}
    </div>
  )
}

标签: javascriptreactjs

解决方案


您对 AddTodo 组件的定义与将您的 AddTodo 组件添加到 DOM 之间存在不匹配。在 Addtodo.js 中,您的函数签名为:

const Addtodo = () => {

因此 Addtodo 组件不希望将任何道具传递给它。

在 App.js 中,您尝试使用以下命令将组件添加到 DOM:

<AddTodo Addtodo={Addtodo} />

因此,您要求使用名为 Addtodo 的道具渲染组件,但如前所述,在组件的定义中,它不期望接收任何道具。

您需要决定是否想要/需要 AddTodo 组件来接收道具。

如果您希望它接收 AddTodo 属性,您可以将函数定义更改为:

const Addtodo = ({ AddTodo }) => {

另外,请确保在导出 Addtodo 组件时,将其导出为默认导出,因为当前代码中的大小写不一致(定义为 Addtodo,但尝试在 App.js 中呈现为 AddTodo)。但是,如果这是默认导出,则无关紧要。确保 AddTodo 的导入语句与渲染 AddTodo 时相同。

明确地说,确保您export default Addtodo在 Addtodo.js 中确保 add todo 组件的导入语句是相同的。因此,如果 App.js 的顶部显示import AddTodo from './Addtodo',那么当您稍后在文件中渲染组件时,它会像<AddTodo />. 如果导入为import Addtodo from './Addtodo',则组件呈现为<Addtodo>(大小写必须一致)

如果这不是最清楚的解释,我深表歉意,我不确定我提到的某些事情的实际术语是什么,但我希望你明白我想说的话。


推荐阅读