【发布时间】:2020-02-08 18:12:10
【问题描述】:
我只是好奇是否可以在 Context API 中使用 Context API。例如,我将有一个 AppState 的 Context API,并希望在另一个处理 WebSocket 连接的 Context API 中使用它?
【问题讨论】:
标签: reactjs react-native websocket react-context
我只是好奇是否可以在 Context API 中使用 Context API。例如,我将有一个 AppState 的 Context API,并希望在另一个处理 WebSocket 连接的 Context API 中使用它?
【问题讨论】:
标签: reactjs react-native websocket react-context
受 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
*/
}
【讨论】:
这是使用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 />
}
【讨论】:
让我解释一下如何同时使用两个不同的上下文。
第一步: 你需要创建两个不同的上下文
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>
);
}
【讨论】: