【问题标题】:React FC Context & Provider Typescript Value IssuesReact FC 上下文和提供者打字稿值问题
【发布时间】:2020-05-03 18:17:47
【问题描述】:

试图在似乎需要传入一个值的应用程序上实现全局上下文,其目的是 API 将返回一个组织列表到可用于显示和后续 API 调用的上下文。

当尝试将 <Provider> 添加到 App.tsx 时,应用程序抱怨该值尚未定义,而我正在使用 useEffect() 模拟 API 响应。

代码如下:

类型types/Organisations.ts

export type IOrganisationContextType = {
  organisations: IOrganisationContext[] | undefined;
};

export type IOrganisationContext = {
  id: string;
  name: string;
};

export type ChildrenProps = {
  children: React.ReactNode;
};

上下文contexts/OrganisationContext.tsx

export const OrganisationContext = React.createContext<
  IOrganisationContextType
>({} as IOrganisationContextType);

export const OrganisationProvider = ({ children }: ChildrenProps) => {
  const [organisations, setOrganisations] = React.useState<
    IOrganisationContext[]
  >([]);

  React.useEffect(() => {
    setOrganisations([
      { id: "1", name: "google" },
      { id: "2", name: "stackoverflow" }
    ]);
  }, [organisations]);

  return (
    <OrganisationContext.Provider value={{ organisations }}>
      {children}
    </OrganisationContext.Provider>
  );
};

用法App.tsx

const { organisations } = React.useContext(OrganisationContext);
  return (
    <OrganisationContext.Provider>
      {organisations.map(organisation => {
        return <li key={organisation.id}>{organisation.name}</li>;
      })}
    </OrganisationContext.Provider>
  );

问题 #1:

Property 'value' is missing in type '{ children: Element[]; }' but required in type 'ProviderProps<IOrganisationContextType>'.

问题 #2:

列表未在App.tsx 上呈现

代码沙盒:https://codesandbox.io/s/frosty-dream-07wtn?file=/src/App.tsx

【问题讨论】:

    标签: reactjs typescript react-context


    【解决方案1】:

    您需要注意以下几点:

    1. 如果我正确阅读了代码的意图,您希望在App.tsx 中呈现OrganisationProvider 而不是OrganisationContext.Provider。 OrganisationProvider 是用于设置假数据的自定义包装器。
    2. 修复此问题后,您将陷入无限渲染循环,因为在OrganisationProvider 组件中,useEffect 设置了organisations 值,然后在organisations 更改时运行。您可能可以将其设置为空数组值[],因此数据仅在初始渲染时设置一次。
    3. 您试图在提供程序位于其上方的树中之前使用上下文。您需要重新构建它,以便内容提供者始终位于任何尝试使用上下文的组件之上。您还可以考虑使用上下文消费者组件,这样您就不需要创建另一个组件。

    通过这些建议的更新,您的 App.tsx 可能如下所示:

    import * as React from "react";
    import "./styles.css";
    import {
      OrganisationContext,
      OrganisationProvider
    } from "./contexts/OrganisationContext";
    
    export default function App() {
      return (
        <OrganisationProvider>
          <OrganisationContext.Consumer>
            {({ organisations }) =>
              organisations ? (
                organisations.map(organisation => {
                  return <li key={organisation.id}>{organisation.name}</li>;
                })
              ) : (
                <div>loading</div>
              )
            }
          </OrganisationContext.Consumer>
        </OrganisationProvider>
      );
    }
    

    以及OrganisationsContext.tsx 中更新的useEffect

      React.useEffect(() => {
        setOrganisations([
          { id: "1", name: "google" },
          { id: "2", name: "stackoverflow" }
        ]);
      }, []);
    

    【讨论】:

    • 这个问题困扰了我一段时间,感谢您快速详细的回复!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 2019-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多