首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在自己的单独文件中创建React上下文?

如何在自己的单独文件中创建React上下文?
EN

Stack Overflow用户
提问于 2020-06-14 05:53:26
回答 1查看 748关注 0票数 0

我正在学习React并使用上下文构建一个项目。最初,我在App.js组件中构建上下文,但为了使App.js更清晰,我希望将其分离到自己的文件中。然而,我很难弄清楚这是如何做到的,或者甚至是可能的。我认为我被卡住的部分是如何提供上下文。我在下面粘贴了新的上下文文件和App.js,其中注释掉了原始的上下文结构。有人知道我是怎么做到这一点的吗?

代码语言:javascript
运行
复制
// TaskManipulatorContext
import React, { useReducer } from "react";
import AddTask from "../Components/dnd_components/AddTask";

export const TaskManipulatorContext = React.createContext();

const taskManipulatorInitialState = {
  panelData: {
    height: 50,
    open: false,
    title: "title",
    content: "content",
  },
  newTask: false,
  deleteTask: false,
  taskContainer: null,
};

const taskManipulatorReducer = (state, action) => {
  switch (action.type) {
    case "addTask-botPanel":
      // Brings up bottom panel to add new task
      return {
        ...state,
        panelData: {
          ...state.panelData,
          height: 20,
          open: true,
          title: "Add Task",
          content: <AddTask />,
        },
        taskContainer: {
          ...state.taskContainer,
          ...action.value,
        },
      };

    case "addTask-submitTask":
      // Submits task and adds it to list
      return {
        ...state,
        panelData: {
          ...state.panelData,
          closing: true,
        },
        newTask: true,
        taskContainer: {
          ...state.taskContainer,
          newTask: action.value,
        },
      };

    case "reset":
      // Reset back to initial state
      return taskManipulatorInitialState;
    default:
      return taskManipulatorInitialState;
  }
};

const [state, dispatch] = useReducer(
  taskManipulatorReducer,
  taskManipulatorInitialState
);
代码语言:javascript
运行
复制
// App.js
import React, { useContext } from "react";
import "./index.css";
import RenderXMilageBoxes from "./Components/RenderXMilageBoxes";
import BottomPanel from "./Components/BottomPanel";
import AddTask from "./Components/dnd_components/AddTask";
import { TaskManipulatorContext } from "./Contexts/TaskManipulatorContext";

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * * CONTEXTS  * * * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// export const TaskManipulatorContext = React.createContext();

// const taskManipulatorInitialState = {
//   panelData: {
//     height: 50,
//     open: false,
//     title: "title",
//     content: "content",
//   },
//   newTask: false,
//   deleteTask: false,
//   taskContainer: null,
// };

// const taskManipulatorReducer = (state, action) => {
//   switch (action.type) {
//     case "addTask-botPanel":
//       // Brings up bottom panel to add new task
//       return {
//         ...state,
//         panelData: {
//           ...state.panelData,
//           height: 20,
//           open: true,
//           title: "Add Task",
//           content: <AddTask />,
//         },
//         taskContainer: {
//           ...state.taskContainer,
//           ...action.value,
//         },
//       };

//     case "addTask-submitTask":
//       // Submits task and adds it to list
//       return {
//         ...state,
//         panelData: {
//           ...state.panelData,
//           closing: true,
//         },
//         newTask: true,
//         taskContainer: {
//           ...state.taskContainer,
//           newTask: action.value,
//         },
//       };

//     case "reset":
//       // Reset back to initial state
//       return taskManipulatorInitialState;
//     default:
//       return taskManipulatorInitialState;
//   }
// };

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * * * * * * * * * * * * MAIN COMPONENT  * * * * * * * * * * * *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
function App() {
  // Contexts
  // const [state, dispatch] = useReducer(
  //   taskManipulatorReducer,
  //   taskManipulatorInitialState
  // );

  const taskManipulatorContext = useContext(TaskManipulatorContext);

  return (
    <div>
      <taskManipulatorContext.Provider
        value={{
          state,
          dispatch,
        }}
      >
        <RenderXMilageBoxes currentMiles={5001} numFutureServices={5} />
        <BottomPanel panelData={state.panelData} />
      </taskManipulatorContext.Provider>
    </div>
  );
}

export default App;
EN

回答 1

Stack Overflow用户

发布于 2020-06-14 06:27:17

我更喜欢这样做的方式是创建一个上下文,然后为提供者和useContext钩子提供相同的上下文,以便在组件中使用。

它看起来像这样:

TaskManiupulatorContext.js

代码语言:javascript
运行
复制
const TaskManipulatorContext = createContext({})

// dispatcher logic

export const TaskManipulatorContextProvider = () => {

    const [state, dispatch] = useReducer(
        taskManipulatorReducer,
        taskManipulatorInitialState
    );

    // You can choose to wrap this in a useMemo if you want to be extra careful about potential rerenders
    const taskManipulatorContextStore = {
        state,
        dispatch,
    }

    return <TaskManipulatorContext.Provider value={taskManipulatorContextStore}>{children}</TaskManipulatorContext.Provider>
}

export const useTaskManipulatorContext = () => useContext(TaskManipulatorContext)

然后,通过使用提供者包装您的应用程序,使上下文在应用程序级别可用:

App.js

代码语言:javascript
运行
复制
import { TaskManipulatorContextProvider } from './TaskManipulatorContext'

// app logic

const App = () => {
  return (
    <TaskManipulatorContextProvider>
      <App />
    </TaskManipulatorContextProvider>
  )
}

现在,您可以从应用程序内的任何组件导入您的useTaskManipulatorContext挂钩并使用它:

SomeComponent.js

代码语言:javascript
运行
复制
import { useTaskManipulatorContext } from './TaskManipulatorContext'

export const SomeComponent = () => {

  const taskManipulatorCtx = useTaskManipulatorContext()

  const someFunctionWhichUpdatesContextState = (action) => {
    taskManipulatorCtx.dispatch(action)
  }

  return (
    <div>
      <text>{'Here is some state from the context'}</text>
      <text>{taskManipulatorCtx.state}</text>
    </div>
  )
}

请注意,采用这种方法可以在很大程度上控制上下文中的访问模式。例如,如果您不希望组件为了更改状态而直接访问分派,您可以在提供程序中创建一个方法来分派某些操作,并将其导出为您的函数可以使用的方法(即。您不需要依赖您的组件或使用您的组件的开发人员来了解如何更新状态的确切行为/实现)。

代码语言:javascript
运行
复制
const taskManipulatorContextStore = {
  state,
  addTask: (taskToAdd) = dispatch(actions.add, taskToAdd)
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62365993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档