我正在使用 nextjs 和 react
域:一个输入管理系统,其中文档可以直接与收件箱或任务相关联。取决于配置。
问题陈述: 根据环境变量,我想提供取决于不同提供商的不同收件箱:
//index.page.tsx
const InboxPage: NextPageWithLayout = () => {
const {supportTasks} = useConfiguration()
const taskInbox = () =>
<InboxProvider>
<TaskProvider>
<DocumentsProvider>
<TaskInbox/>
</DocumentsProvider>
</TaskProvider>
</InboxProvider>;
const documentInbox = () =>
<InboxProvider>
<DocumentsProvider>
<DocumentInbox/>
</DocumentsProvider>
</InboxProvider>;
return (
<>
{supportTasks ? taskInbox() : documentInbox()}
</>
);
};
我想要** DocumentsProvider** 的两种不同实现,调用者不必担心系统当前运行的是哪种“配置”模式。呼叫者应该始终能够呼叫:
const { documents, setSelectedDocuments, selectedDocuments } = useDocuments();
并根据 Provider 的实现(inboxDocument 或 taskDocument)接收文档。
我尝试使用以下通用 useDocuments.tsx 文件实现此目的,其中根据配置应注入两个可用实现的 contextValue:
//useDocuments.tsx
//imports omitted
export type DocumentContextProps = {
//some methods and values
};
type Contexts = {
inbox: DocumentContextProps;
task: DocumentContextProps;
};
const DocumentsContext = React.createContext<DocumentContextProps | null>(null);
export const useDocuments = (): DocumentContextProps => {
const documentsContext = useContext(DocumentsContext);
if (!documentsContext) {
throw new Error('useDocuments must be used within a DocumentsProvider');
}
return documentsContext;
};
const DocumentsProvider: React.FunctionComponent<PropsWithChildren> = ({children}) => {
const {supportTasks} = useConfiguration();
const contexts: Contexts = {
inbox: useContext(InboxDocumentsContext),
task: useContext(TaskDocumentsContext),
};
const contextValue = supportTasks ? contexts.task : contexts.inbox;
return <DocumentsContext.Provider value={contextValue}>
{children}
</DocumentsContext.Provider>;
};
export default DocumentsProvider;
两个实现是:
// useInboxDocuments.tsx
export const TaskDocumentsContext = React.createContext<DocumentContextProps>(
{
//default values
}
);
const TaskDocumentsProvider: React.FunctionComponent<PropsWithChildren> = ({ children }) => {
//providing business-logic
return (<TaskDocumentsContext.Provider value={{
//values
}}>{children}</TaskDocumentsContext.Provider>)
};
export default TaskDocumentsProvider;
和:
//useTaskDocuments.tsx
export const TaskDocumentsContext = React.createContext<DocumentContextProps>(
{
//default values
}
);
const TaskDocumentsProvider: React.FunctionComponent<PropsWithChildren> = ({ children }) => {
//providing business-logic
return (<TaskDocumentsContext.Provider value={{
// values
}}>{children}</TaskDocumentsContext.Provider>)
};
export default TaskDocumentsProvider;
此实现失败,因为检查 useDocuments (useDocuments.tsx) 会抛出错误:
if (!documentsContext) { throw new Error('useDocuments must be used within a DocumentsProvider'); }
我怎样才能将这两个提供者合二为一。请注意,两个提供程序都实现了完全相同的方法。