我可以在 Context API 中使用 React Context API 还是必须合并它们?

Can I use the React Context API inside a Context API or do I have to merge them?

我只是好奇是否可以在上下文 API 中使用上下文 API。例如,我会有一个 AppState 的上下文 API,并想在另一个处理 WebSocket 连接的上下文 API 中使用它?

这是使用 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 />
}

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

useMultipleContexts(){
  const contextOne = useContext(ContextOne);
  const contextTwo = useContext(ContextTwo);

  /**
   * Do something with both contexts
   * in a custom hook that can be used
   * multiple times with the same state
   */


}

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

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

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);

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

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

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>
  );
}