无法使用反应上下文传递状态

Unable to pass down state using react context

我正在尝试成功使用 React Context,但我遇到了很多麻烦。我什至无法成功地将任何一级传递给提供者的直系子级,结果我在这个阶段得到的只是控制台中的“x 未定义”错误。我正在为上下文使用一个单独的 class 和一个自定义挂钩来管理我的状态数据。

App.js(TodoProvider 组件围绕其子项扭曲)-

import logo from './logo.svg';
import './App.css';
import React, {createContext, useContext} from "react"
import TodoItem from './Components/Other/TodoItem';
import TodoList from './Components/List/TodoList';
import TodoAdd from './Components/Forms/TodoAdd';
import CompletedTaskList from './Components/List/CompletedTaskList';
import useTodo from './libs/useTodo';
import {TodoContext, TodoProvider} from "./Contexts/TodoContext"

function App() {
  const {
    todoArray, setTodoArray,
    completedTaskArray,
    addCompletedItem,
    addTodoItem
  } = useContext(TodoContext);

  return (
    <TodoProvider
      value={
        todoArray, setTodoArray,
        completedTaskArray,
        addCompletedItem,
        addTodoItem
      }
    >
      <div className="App">
        <div className='card' id='mainCard'>
          <div className='card-header' id='mainCardHeader'><h4>Todo List</h4></div>
          <TodoList/>
          <TodoAdd
          />
          <CompletedTaskList
          />
        </div>
      </div>
    </TodoProvider>
    )
}

export default App;

TodoContext.js(我的上下文)-

import React, {createContext} from "react";
import useTodo from "../libs/useTodo";

const TodoContext = createContext();

const TodoProvider = ({children}) => {
    const {
        todoArray, setTodoArray,
        completedTaskArray,
        addCompletedItem,
        addTodoItem
      } = useTodo();
    return (
        <TodoContext.Provider
            value={
                todoArray, setTodoArray,
                completedTaskArray,
                addCompletedItem,
                addTodoItem
            } 
        >
            {children}
        </TodoContext.Provider>
    )
}

export {TodoContext, TodoProvider}

useTodo.js(我的自定义挂钩来管理状态)

import React, {useState} from "react"

const useTodo = () => {
      
  const [todoArray, setTodoArray] = useState([{id: 1,todoTitle: "Code", todoDescription: "Practice React"},{id: 2,todoTitle: "Clean", todoDescription: "Wash dishes, wipe surfaces"}]);
  const [completedTaskArray, setCompletedTaskArray] = useState(["Wake up", "Make Bed"]);

  const [currentId, setCurrentId] = useState(3);

  const addTodoItem = (todoTitleInputItem, todoDescriptionInputItem) => {
    let todoTitle = todoTitleInputItem;
    let todoDescription = todoDescriptionInputItem;
    let id = currentId;
    setCurrentId(currentId+1)
    setTodoArray(todoArray => [...todoArray, {id,todoTitle, todoDescription}]);
  }

  const addCompletedItem = ({todoTitle}) => {
    setCompletedTaskArray(completedTaskArray => [...completedTaskArray, todoTitle]);
  }

  return {
      todoArray, setTodoArray,
      completedTaskArray, setCompletedTaskArray,
      addTodoItem,
      addCompletedItem
  }
}

export default useTodo;

CompletedTasklist(我在其中一个子项中使用上下文的实现示例)-

import { useContext } from "react";
import {TodoContext, TodoProvider} from "../../Contexts/TodoContext"
const CompletedTaskList = () => {

    const {
        completedTaskArray
    } = useContext(TodoContext);


    return (
        <div className="card todo-item">
            <div className="card-header">
                <h3> Completed Task</h3>
            </div>
            <div className="card-body">
                <ul className="list-group ">
                    {completedTaskArray.map((item,index) => {
                        return <li className="list-group-item list-group-item-success" key={index}>{item}</li>
                    })}
                </ul>
            </div>
        </div>
    )
}

export default CompletedTaskList;   

我已经尝试解决这个问题一段时间了,但无法解决这个问题。

App.js

import React, { createContext, useContext } from 'react';
import CompletedTaskList from './comp';
import { TodoProvider } from './context';

function App() {
  // you dont need useTodo, or TodoContext here
  return (
    <TodoProvider>
      {/** todo Provider is a wrapper, you dont need to pass value as prop again, you are already doing it */}
      <div className="App">
        <div className="card" id="mainCard">
          <div className="card-header" id="mainCardHeader">
            <h4>Todo List</h4>
          </div>

          <CompletedTaskList />
        </div>
      </div>
    </TodoProvider>
  );
}

export default App;

上下文

import React, { createContext } from 'react';
import useTodo from './useTodo';

// Define default values of your context data.
// otherwise everything would be undefined and you need to handle it everywhere
// you are using context
const TodoContext = createContext({
  todoArray: [],
  setTodoArray: () => {},
  completedTaskArray: [],
  addCompletedItem: () => {},
  addTodoItem: () => {},
});

const TodoProvider = ({ children }) => {
  const {
    todoArray,
    setTodoArray,
    completedTaskArray,
    addCompletedItem,
    addTodoItem,
  } = useTodo();
  return (
    <TodoContext.Provider
      value={{
        // <--- you were passing value incorrectly here, it should be an object
        // you passed it as (......) instead of {...}
        // curly braces not paranthesis
        todoArray,
        setTodoArray,
        completedTaskArray,
        addCompletedItem,
        addTodoItem,
      }}
    >
      {children}
    </TodoContext.Provider>
  );
};

export { TodoContext, TodoProvider };

重贴上面分享的link答案