Реагировать на ошибку области видимости useContext + TypeScript - PullRequest
1 голос
/ 09 мая 2020

Пробуем работать с context / hooks и TypeScript впервые. Поскольку я отправляю значение и функцию (функция отправки / установки), я использую шаблон разделения Provider, описанный в этого сообщения в блоге под заголовком «Шаблон B - A Разделение ".

Следующая настройка работает должным образом, пока я экспортирую свои объекты StateContext и DispatchContext и импортирую их для использования с useContext в компоненте-потребителе.

    // src/components/index.tsx
    ReactDOM.render(
      <Router>
        <MyProvider>
          <MyComponent />
        </MyProvider>
      </Router>,
      document.getElementById("root")
    );
    // src/providers/myProvider.tsx
    import React, { useState, useContext } from "react";

    type MyProviderProps = { children: React.ReactNode };
    type State = string | undefined;
    type Dispatch = (value: State) => void;

    export const StateContext = React.createContext<State>(undefined);
    export const DispatchContext = React.createContext<Dispatch | undefined>(undefined);

    export function MyProvider({ children }: MyProviderProps) {
      const [state, dispatch] = useState<State>(undefined);

      return (
        <StateContext.Provider value={state}>
          <DispatchContext.Provider value={dispatch}>
            {children}
          </DispatchContext.Provider>
        </StateContext.Provider>
      );
    }
    // src/components/MyComponent.tsx
    import React from "react";
    import {
      StateContext,
      DispatchContext,
    } from "../providers/myProvider";

    export default function MyComponent() {
      const myMessage = React.useContext(StateContext);
      const setMyMessage = React.useContext(DispatchContext);


      return (
        <div>{myMessage}</div>
      );
    }

Однако , если я попытаюсь создать вспомогательные функции для useContext(XyzContext), я получаю сообщение об ошибке, потому что контекст undefined: useMyMessage must be used within MyProvider. Я не могу понять, почему эта вспомогательная функция вызывает проблему.

    // src/providers/myProvider.tsx
    import React, { useState, useContext } from "react";

    type MyProviderProps = { children: React.ReactNode };
    type State = string | undefined;
    type Dispatch = (value: State) => void;

    const StateContext = React.createContext<State>(undefined);
    const DispatchContext = React.createContext<Dispatch | undefined>(undefined);

    export function MyProvider({ children }: MyProviderProps) {
      const [state, dispatch] = useState<State>(undefined);

      return (
        <StateContext.Provider value={state}>
          <DispatchContext.Provider value={dispatch}>
            {children}
          </DispatchContext.Provider>
        </StateContext.Provider>
      );
    }

    export function useMyMessage() {
      const context = useContext(StateContext);
      if (!context) {
        throw new Error("useMyMessage must be used within MyProvider");
      }
      return context;
    }
    // src/components/MyComponent.tsx
    import React from "react";
    import {
      useMyMessage,
      DispatchContext,
    } from "../providers/myProvider";

    export default function MyComponent() {
      const myMessage = useMyMessage();
      const setMyMessage = React.useContext(DispatchContext);


      return (
        <div>{myMessage}</div>
      );
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...