React Native && Firebase && useContext - «TypeError: null не является объектом (оценка '_ref.user')» с ошибкой onAuthStateChanged

Ошибка возникает в моем файле useCachedResources.ts, но я не уверен, почему. Это три файла, с которыми я работаю. Я подозреваю, что это связано с тем, что значение изначально было нулевым в первый раз, но я условно отображаю свои стеки навигации Auth и App. Кроме того, с шаблоном был предоставлен useCachedResources, поэтому, может быть, мне следует добавить в него firebase onAuthStateChanged?

Аутентикатидеусерпровидер.tsx

import { useState, createContext } from 'react';

export interface IUser {
  uuid: string;
  email: string | null;
}

export type AuthContextType = {
  user: IUser;
  setUser: (newUser: IUser | null) => void;
};

export const AuthenticatedUserContext = createContext<AuthContextType | null>(null);

export const AuthenticatedUserProvider = ({ children }: { children: React.ReactNode }) => {
  const [user, setUser] = useState<IUser | null>(null);

  return (
    <AuthenticatedUserContext.Provider value={user ? { user, setUser } : null}>
      {children}
    </AuthenticatedUserContext.Provider>
  );
};

навигация.ts

export default function Navigation({ colorScheme }: { colorScheme: ColorSchemeName }) {
  const { user } = useContext(AuthenticatedUserContext) as AuthContextType;

  return (
    <NavigationContainer linking={LinkingConfiguration} theme={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
      {user ? <AppStack /> : <AuthStack />}
    </NavigationContainer>
  );
}

использоватьCachedResources.ts

export default function useCachedResources() {
  const { user, setUser } = useContext(AuthenticatedUserContext) as AuthContextType;
  const [isLoadingComplete, setLoadingComplete] = useState(false);

  useEffect(() => {
    async function loadResourcesAndDataAsync() {
      try {
        SplashScreen.preventAutoHideAsync();

        await Font.loadAsync({
          ...FontAwesome.font,
          'poppins-400': require('../assets/fonts/poppins-400.ttf'),
          'poppins-700': require('../assets/fonts/poppins-700.ttf'),
          'poppins-900': require('../assets/fonts/poppins-900.ttf'),
        });

        const unsubscribeAuthStateChanged = onAuthStateChanged(auth, (authenticatedUser) => {
          authenticatedUser ? setUser({ uuid: authenticatedUser.uid, email: authenticatedUser.email }) : setUser(null);
        });

        return unsubscribeAuthStateChanged;
      } catch (e) {
        console.warn(e);
      } finally {
        setLoadingComplete(true);
        SplashScreen.hideAsync();
      }
    }

    loadResourcesAndDataAsync();
  }, [user]);

  return isLoadingComplete;
}

enter image description here

Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
Четыре эффективных способа центрирования блочных элементов в CSS
Четыре эффективных способа центрирования блочных элементов в CSS
У каждого из нас бывали случаи, когда нам нужно отцентрировать блочный элемент, но мы не знаем, как это сделать. Даже если мы реализуем какой-то...
1
0
14
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку вы инициализируете свой контекст с помощью null, вы не можете использовать деструктурирование. Например, это...

const { user } = null;

в браузере выдает следующую ошибку

Uncaught TypeError: Cannot destructure property 'user' of 'null' as it is null.

Мой совет состоял бы в том, чтобы инициализировать ваш контекст фиктивным значением. Это также избавит вас от необходимости использовать as AuthContextType везде.

export type AuthContextType = {
  user: IUser | null; // make user optional instead of the context
  setUser: (newUser: IUser | null) => void;
};

// initialise with a dummy / no-op context
export const AuthenticatedUserContext = createContext<AuthContextType>({
  user: null,
  setUser: () => {}
});

export const AuthenticatedUserProvider: React.FC = ({ children }) => {
  const [user, setUser] = useState<IUser | null>(null);

  return (
    <AuthenticatedUserContext.Provider value={{ user, setUser }}>
      {children}
    </AuthenticatedUserContext.Provider>
  );
};

Другие вопросы по теме