Реагируйте F C Контекст и проблемы значения машинописного текста провайдера - PullRequest
1 голос
/ 03 мая 2020

Пытаясь реализовать глобальный контекст в приложении, которое, по-видимому, требует передачи значения, предполагается, что API вернет список организаций в контекст, который можно использовать для отображения и последующих вызовов API.

При попытке добавить <Provider> в App.tsx приложение жалуется, что значение не было определено, в то время как я высмеиваю ответ API с кодом useEffect().

следующим образом :

Типы 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

Codesandbox: https://codesandbox.io/s/frosty-dream-07wtn?file= / src / App.tsx

1 Ответ

1 голос
/ 03 мая 2020

Есть несколько вещей, на которые вам нужно обратить внимание в этом:

  1. Если я правильно читаю намерение кода, вы хотите отобразить OrganisationProvider в App.tsx вместо OrganisationContext.Provider. OrganisationProvider - это пользовательская оболочка для установки поддельных данных.
  2. Как только это будет исправлено, вы столкнетесь с бесконечным рендерингом l oop, потому что в компоненте 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>
  );
}

и обновленный useEffect в OrganisationsContext.tsx:

  React.useEffect(() => {
    setOrganisations([
      { id: "1", name: "google" },
      { id: "2", name: "stackoverflow" }
    ]);
  }, []);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...