我想使用 React 创建待办事项应用程序,我使用 useContext 挂钩,但遇到以下问题
无效的挂钩调用。钩子只能在函数组件的主体内部调用。发生这种情况可能是由于以下原因之一:
import { useState } from 'react'
import TodoStore from './Hooks/TodoStore'
import './App.css'
import TodosForm from './Component/TodosForm'
import Tasks from './Component/Tasks'
function App() {
const [todolist,setTodoList]=useState([]);
const fillTodoList=(todo)=>{
setTodoList([todo,...todolist])
}
return (
<TodoStore.Provider value={setTodoList}>
<TodosForm fillTodoList={fillTodoList} />
<Tasks alltasks={todolist} setList={setTodoList}/>
</TodoStore.Provider>
)
}
export default App
import React from 'react'
import Completed from '../Operations/Completed'
import deleteTask from '../Operations/deleteTask'
function Tasks(props) {
return (
<div>
{
props.alltasks.map((item)=><div key={item.id}>
<span onClick={()=>Completed(item.id,props.alltasks)}>{item.text}</span>
<button onClick={()=>deleteTask(item.id,props.alltasks)}>X</button>
</div>)
}
</div>
)
}
export default Tasks
import { useContext } from "react"
import TodoStore from "../Hooks/TodoStore"
const deleteTask=(id,alltasks)=>{
const {setList}=useContext(TodoStore);
const result=alltasks.filter((item)=>item.id!=id)
setList([...result])
}
export default deleteTask
问题来自于你的
deleteTask
函数:你正在使用一个钩子(useContext
),但这个函数本身并不是一个钩子。
你必须明白,React 必须为组件的每次渲染渲染精确的相同数量的钩子。所以你不能在嵌套函数中使用钩子(除非它也是一个钩子)
在上下文中使用 reducer,这样您就不必编写多个操作来修改上下文。它是通量模式的基础。它将让你拥有更简洁、更进化的代码。
import { useContext } from "react"
import TodoStore from "../Hooks/TodoStore"
// Note that hook must always starts with "use"
const useDeleteTask = () => {
const {setList} = useContext(TodoStore);
return (id, alltasks) => {
const result = alltasks.filter((item) => item.id != id)
setList([...result])
}
}
export default useDeleteTask
您的任务组件
function Tasks(props) {
const deleteTask = useDeleteTask()
return (
<div>
{
props.alltasks.map((item) => <div key={item.id}>
<span onClick={()=>Completed(item.id,props.alltasks)}>{item.text}</span>
<button onClick={() => deleteTask(item.id,props.alltasks)}>X</button>
</div>)
}
</div>
)
}
请注意,您不必传递
allTodos
属性,因为它是上下文的一部分,因此您可以使用 useContext
获取它。
希望能解决您的问题。