0

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

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;   

我一直在尝试解决这个问题一段时间,但无法解决这个问题。

4

1 回答 1

1

应用程序.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 };

从我上面分享的链接中重新获得答案。

于 2022-01-15T11:42:31.013 回答