Вызывается функция значения контекста провайдера по умолчанию, а не функция внутри провайдера - PullRequest
0 голосов
/ 07 апреля 2020

У меня проблема, когда вызывается значение контекста по умолчанию вместо функции внутри провайдера.

Из-за Typescript требуется определение, а undefined не является идеальным решение.

interface ContextProps {
  error: ApiError | null;
  errorUI: React.ReactElement | null;
  handleError: (value: ApiError | null) => void;
}

export const ErrorContext = React.createContext<ContextProps>({
  error: null,
  handleError: (_err: ApiError | null) => { console.log('hi'); }, // <<-- this function gets triggered, not the one inside the Provider
});

const ErrorProvider: FC = ({ children }) => {
  const [error, setError] = useState<ApiError | null>(null);
  const handleError = (err: ApiError) => setError(err);
  return (
    <ErrorContext.Provider value={{ error, handleError }}>
      {children}
    </ErrorContext.Provider>
  );
}
// HOOK:
const useDisplayError = () => {
  const { handleError } = useContext(ErrorContext);
  return useCallback(
    (error) => {
      handleError(error);
    },
    [handleError]
  );
};

Вот как выложено приложение для потребления:

ReactDOM.render(
  <Router history={history}>
    <AppProviders>
      <App />
    </AppProviders>
  </Router>,
document.getElementById('root'));

const AppProviders: FC = ({ children }) => {
  return (
    <AuthProvider>
      <ThemeProvider theme={theme}>
        <GlobalStyle />
        <LoadingProvider>
          <ErrorProvider>{children}</ErrorProvider>
        </LoadingProvider>
      </ThemeProvider>
    </AuthProvider>
  );
};

const App: FC = () => {
  const { token } = useAuth();

  return token ? <Authenticated /> : <Unauthenticated />;
};

const Unauthenticated: FC = () => {
  return <Login />;
};

// Крюк, потребляющий компоненты

const Login: FC = () => {
  const { login } = useAuth();
  const displayError = useDisplayError();

const handleSubmit = (event: MouseEvent) => {
    event.preventDefault();
    setStatus(Status.LOADING);
    try {
      login({ email, password });
    } catch (e) {
      displayError(e); // hook gets called here
    }
  };
return <div />
};

Функция из hook handleError вызывается правильно из потребляющего компонента самого Hook. Однако вызванный handleError отображается обратно на версию функции из createContext, а не функции внутри самого провайдера.

Поэтому вызывается console.log вместо желаемого действия по обновлению состояния изнутри провайдера. Почему это?

1 Ответ

0 голосов
/ 07 апреля 2020

проверьте порядок ваших провайдеров, если контекст не работает!

Этот порядок работает:

    const AppProviders: FC = ({ children }) => {
  return (
    <ThemeProvider theme={theme}>
      <GlobalStyle />
      <LoadingProvider>
        <ErrorProvider>
          <AuthProvider>{children}</AuthProvider>
        </ErrorProvider>
      </LoadingProvider>
    </ThemeProvider>
  );
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...