【问题标题】:Can I use the React Context API inside a Context API or do I have to merge them?我可以在 Context API 中使用 React Context API 还是必须合并它们?
【发布时间】:2020-02-08 18:12:10
【问题描述】:

我只是好奇是否可以在 Context API 中使用 Context API。例如,我将有一个 AppState 的 Context API,并希望在另一个处理 WebSocket 连接的 Context API 中使用它?

【问题讨论】:

    标签: reactjs react-native websocket react-context


    【解决方案1】:

    受 Joseph 回答的启发,我正在考虑在自定义挂钩中一起使用这两个上下文 api。

    useMultipleContexts(){
      const [contextOne, setContextOne] = useContext(ContextOne);
      const [contextTwo, setContextTwo] = useContext(ContextTwo);
    
      /**
       * Do something with both contexts
       * in a custom hook that can be used
       * multiple times with the same state
       */
    
    
    }
    
    

    【讨论】:

      【解决方案2】:

      这是使用hooks 代替上下文的好场景。

      // custom hook
      function useAppState() {
        //add handlers here
      
        return appState;
      }
      
      function WebSocket() {
        const appState = useAppState();
      
        // do something (i.e reconnect) every time appState changes
        useEffect(() => { /* do something */, [appState])
      }
      
      function App() {
        return <WebSocket />
      }
      

      【讨论】:

      • appState 以及 Websocket 连接的状态需要在整个应用程序中是全局的。只要我想,我想最好的办法是制作两个单独的上下文 api,并在自定义钩子中使用它们。
      • 所以我不会说而是和上下文api一起
      • @thilolg 确定可行。请记住区分副作用与提供的值。
      【解决方案3】:

      让我解释一下如何同时使用两个不同的上下文。

      第一步: 你需要创建两个不同的上下文

      const AppContext = React.createContext(null);
      const SocketContext = React.createContext(null);
      

      第二步: 你需要实现你的自定义钩子。

      const UseSharedLogic = () => {
         // your common logic
      }
      

      然后使用上下文 API 共享它。

       <AppContext.Provider value={state}>
              <SocketContext.Provider value={UseSharedLogic}>
                <App />
              </DispatchContext.Provider>
            </StateContext.Provider>
      

      第三步: 您需要在需要在其中使用它们的组件中使用这些上下文。

      const state = React.useContext(AppContext);
      const socket = React.useContext(SocketContext);
      

      在这里,您可以同时使用两个上下文,并在另一个上下文中使用一个上下文中的一个值。

      假设套接字上下文有一个名为 connect 的函数,它依赖于应用上下文中的值,你可以这样做。

      socket.connect(state.anyValue);
      

      【讨论】:

      • 我想我必须改进写我的问题。我更关心共享我将在所有其他应用程序的两个上下文中执行的逻辑,并使用我想要共享的这两个上下文创建一个新的全局状态。
      • 您希望如何在两个上下文之间共享逻辑? 上下文 API: 提供了一种通过组件树传递数据的方法,而无需在每个级别手动向下传递道具。你可以,但里面的逻辑。您可以使用它将这个逻辑从组件传递到另一个组件。如果你想共享一个逻辑,你需要实现一个自定义钩子。
      • 那么我宁愿使用自定义钩子然后在上下文 api 中并以这种方式传递它还是在钩子中使用上下文 api 并多次使用它?我的意思是在第二种情况下,我可以将多个上下文与共享逻辑一起使用。
      • 是的,完全正确。我编辑了我的答案,再看看。
      【解决方案4】:

      我会创建一个新的功能组件来包装组件

      假设你有两个组件,如下所示。

      import React from 'react';
      const ContextA = React.createContext({});
      export default ContextA;
      
      import React from 'react';
      const ContextB = React.createContext({});
      export default ContextB;
      

      我通常会避免使用上述模式,因为人们必须猜测您要在上下文中添加什么。相反,我编写了一个提供上下文的功能组件,如下所示

      import { createContext, useContext } from 'react'
      import ContextA from './contexta'
      import ContextB from './contextb'
      
      // The ! is needed in order to allow undefined to be set as the initial value.
      const MyContext = createContext<IMyContextInfo>(undefined!);
      export default ({children}) => {
        const { somethingFromA } = useContext(ContextA);
        const { somethingFromB }= useContext(ContextB);
        return (
          <MyContext.Provider value={{ a: somethingFromA, b: somethingFromB }}>
            {children}
          </MyContext.Provider>
        );
      }
      

      【讨论】:

        猜你喜欢
        • 2019-05-27
        • 2019-09-09
        • 1970-01-01
        • 1970-01-01
        • 2022-12-21
        • 2020-10-22
        • 2019-06-07
        • 2018-09-02
        • 1970-01-01
        相关资源
        最近更新 更多