Контекст React возвращает undefined

Я хочу использовать контекст в React для передачи информации аутентификации дочерним компонентам. Мой поставщик контекста находится в файле с именем AuthContext.js:

import React, { Component, createContext } from 'react';

export const AuthContext = createContext();

class AuthContextProvider extends Component {
    state = {
        isAuthenticated: false
    };
    toggleAuth = () => {
        this.setState({ isAuthenticated: !this.state.isAuthenticated });
    };
    render() {
        return (
            <AuthContext.Provider value={{...this.state, toggleAuth: this.toggleAuth}}>
                {this.props.children}
            </AuthContext.Provider>
        );
    }
}

export default AuthContextProvider;

Но когда я обращаюсь к контексту из дочерних компонентов, он возвращает undefined

import { AuthContext } from "../contexts/AuthContext";

export default function ButtonAppBar() {
    return(
        <AuthContext.Consumer>{(authContext) => {
            console.log(authContext);
        }}</AuthContext.Consumer>
    );
}

После проверки инструментов разработчика React я пришел к выводу, что ButtonAppBar не находится внутри AuthContextProvider. Импорт правильный. Есть ли причина для этого, кроме ошибок импорта?

Снимок экрана инструментов разработчика React

Версия React: 16.9.0


person Anubhav Das    schedule 20.08.2019    source источник
comment
Как вы используете AuthContextProvider? какую версию реакции вы используете?   -  person Federkun    schedule 20.08.2019
comment
@Federkun Я использую React 16.9.0. И я использую потребителя контекста для доступа к контексту ... если это то, о чем вы спрашиваете?   -  person Anubhav Das    schedule 20.08.2019
comment
Я спрашиваю, можете ли вы подтвердить, что AuthContextProvider используется в качестве родительского компонента ButtonAppBar, возможно, предоставьте пример   -  person Federkun    schedule 20.08.2019


Ответы (2)


Если вы посмотрите на эту рабочую панель кодов, вы увидите, что ваш код правильный и должно работать, если вы все сделали правильно.

Причины, по которым это может не работать

  • Может ты неправильно импортируешь? Пожалуйста, проверьте, как вы его импортируете.
  • Может быть ButtonAppBar не внутри AuthContextProvider.

Чтобы контекст работал, потребитель должен находиться внутри провайдера.

Это будет работать

  <AuthContextProvider>
    <ButtonAppBar /> {// consumer inside the provider }
  </AuthContextProvider>

так не пойдет

  <AuthContextProvider>
      ...
  </AuthContextProvider>
  <ButtonAppBar /> {// consumer outside the provider }

На скриншоте из вопроса у вас нет AuthContextProvider обертывания маршрутов, поэтому вы никогда не сможете получить контекст.

Вы неправильно указали код, но я предполагаю, что вам нужно

<App>
    <AuthContextProvider> {// AuthContextProvider wrapping routes so you can get the context}
        <BrowserRouter>
            ...
        </BrowserRouter>
    </AuthContextProvider>
</App>
person Vencovsky    schedule 20.08.2019
comment
Это вторая причина. Я обновил свой вопрос, не могли бы вы взглянуть? - person Anubhav Das; 20.08.2019
comment
@AnubhavDas Расскажите, пожалуйста, где и как вы используете AuthContextProvider и ButtonAppBar. - person Vencovsky; 20.08.2019
comment
На скриншоте вы не используете AuthContextProvider, вы должны поместить его вокруг маршрутизатора, чтобы все маршруты могли иметь этот контекст. - person Vencovsky; 20.08.2019

Замыкает мой друг. Ваш дочерний компонент выполняет функцию anónimo us, и этот обратный вызов выполняется браузером. Если вы введете console.log, вы увидите, что это окно, и, как вы понимаете, у окна нет этой функции.

person Ernesto    schedule 20.08.2019
comment
если у вас console.log this почему? OP никогда не используйте this в ButtonAppBar. как вы понимаете, у окна нет той функции, какая функция? Что нужно сделать OP, чтобы исправить проблему? - person Yury Tarabanko; 20.08.2019