在自定义 ContextProvider 中检索上下文之前操作上下文是否有效?

问题描述 投票:0回答:1

我有一个 React 自定义 ContextProvider 组件。每当调用它时,我都需要在其中设置一个特定的 ID,它将作为所有 CRUD 的基础。现在,它是这样的:

import React, { Dispatch, PropsWithChildren, SetStateAction, createContext, useContext } from "react";


export type RepositoryContext = {
  dispatchDelete: (id: number) => Promise<void>;
  dispatchEdit: (body: SelfCollection, action: EditionAction) => Promise<void>;
  dispatchCreate: (body: ScoPostBody) => Promise<void>;
  loadList: () => Promise<void>;
  loading: boolean;
  data: RepoEntities[];
  setFetchingId: Dispatch<SetStateAction<number | undefined>>;
};

const RepositoryContext = createContext<RepositoryContext | null>(null);

export const useRepository = (id?: number) => {
  const context = useContext(ScoRepositoryContext); // Here is my doubt
  if (id) context?.setFetchingId(id);
  return context;
};

export const RepositoryProvider = ({ children }: PropsWithChildren) => {
  // My context logic here...

  const contextContent = {
    dispatchDelete,
    dispatchEdit,
    dispatchCreate,
    loadList,
    loading,
    data,
    setFetchingId,
  };

  return <ScoRepositoryContext.Provider value={contextContent}>{children}</ScoRepositoryContext.Provider>;
}

然后我像这样包裹我的消费者的父母:

<RepositoryProvider>
  <ConsumerComponent />
</RepositoryProvider>

如果我之后在上下文消费者中设置ID,并导出钩子而不对其进行操作,我知道上面的上下文组件是绝对有效的,如下所示:

export const useRepository = () => useContext(ScoRepositoryContext);

我的疑问是:如果我在返回之前在上下文中进行操作,它是有效的 React/JSX 代码吗?还是我违反了任何钩子规则?

P.S.:在有人说“如果它有效,那就没问题”之前,我需要解释一下:该应用程序违反了一些钩子规则,并返回了在 useEffects/useCalbacks/whatever 内渲染钩子的错误,但问题出在其他地方,因为即使使用“通常”的方法,返回上下文而不对其进行操作,我也会收到错误。这个问题纯粹是理论上的,纯粹出于好奇。

reactjs typescript jestjs
1个回答
0
投票

是的,您可以在应用程序的任何部分使用上下文之前设置上下文的默认状态。您需要将道具/数据传递给它并简单地设置它,然后导出上下文提供程序以供使用。示例...

export const ReactProvider = ({ user, children }) => {
    const [state, dispatch] = useReducer(combined, { user });
    return (
        <AppContext.Provider
            value = {{ state, dispatch }}
            displayName = "My React Context">
            {children}
        </AppContext.Provider>
    );
};

丹尼尔

© www.soinside.com 2019 - 2024. All rights reserved.