【问题标题】:useContext Error: Invalid hook call. Hooks can only be called inside of the body of a function componentuseContext 错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用
【发布时间】:2021-04-19 16:49:03
【问题描述】:

我正在尝试在 React Native Expo 应用程序中使用 Firebase 实现身份验证,但收到指向 useContext 的错误,我在 Routes.js 文件中使用了该错误:

import React, { useContext, useEffect, useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import * as firebase from 'firebase';

import AuthStack from './AuthStack';
import MainTab from './MainTab';
import { AuthUserContext } from './AuthUserProvider';
import LoadingScreen from '../screens/LoadingScreen';

export default function Routes() {
    const [isLoading, setIsLoading] = useState(true);
    const { user, setUser } = useContext(AuthUserContext);

    useEffect(() => {
        const unsubscribeAuth = firebase.auth().onAuthStateChanged(async authUser => {
            try {
                await (authUser ? setUser(authUser) : setUser(null));
                setIsLoading(false);
            } catch (error) {
                console.log(error);
            }
        });
        return unsubscribeAuth;
    }, []);

    if (isLoading) {
        return <LoadingScreen />;
    }

    return (
        <NavigationContainer>
            {user ? <MainTab /> : <AuthStack />}
        </NavigationContainer>
    );
}

我在单独的文件AuthUserProvider.js 中创建AuthUserContext

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

export const AuthUserContext = createContext({});

export const AuthUserProvider = ({ children }) => {
  const [user, setUser] = useState(null);

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

然后我将其用作 App.js 文件中的提供程序:

export default function AppWrapper() {
  const [fontLoaded, setFontLoaded] = useState(false);

  if (!fontLoaded) {
    return (
      <AppLoading 
        startAsync={fetchFonts} 
        onFinish={() => setFontLoaded(true)} 
      />
    );
  }

  const rootReducer = combineReducers({
    cart: cartReducer,
    history: historyReducer
  });
  
  const store = createStore(rootReducer, applyMiddleware(ReduxThunk));

  return (
    <Provider store={store}>
      <AuthUserProvider>
        <Routes />
      </AuthUserProvider>
    </Provider>
  );
}

我几天来一直在寻找答案,但看不出有什么问题。我使用createContextuseContext 的方式有问题吗?任何可能的解决方案的线索都会让我永远感激!

【问题讨论】:

    标签: reactjs react-native firebase-authentication react-hooks


    【解决方案1】:

    错误很可能来自 Redux,storerootReducer 应该在外部范围内:

    const rootReducer = combineReducers({
      cart: cartReducer,
      history: historyReducer,
    });
    
    const store = createStore(rootReducer, applyMiddleware(ReduxThunk));
    
    export default function AppWrapper() {
      const [fontLoaded, setFontLoaded] = useState(false);
    
      if (!fontLoaded) {
        return (
          <AppLoading
            startAsync={fetchFonts}
            onFinish={() => setFontLoaded(true)}
          />
        );
      }
    
      return (
        <Provider store={store}>
          <AuthUserProvider>
            <Routes />
          </AuthUserProvider>
        </Provider>
      );
    }
    

    【讨论】:

    • 感谢您的建议,但仍然出现错误。像我在AppWrapper 中那样拥有两个提供商是否有问题?
    • 您在 AppLoading 中有上下文吗?...请在代码和框中创建一个可重现的示例,这样我们就不会猜测了
    猜你喜欢
    • 2020-07-22
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-25
    • 1970-01-01
    • 2019-11-01
    相关资源
    最近更新 更多