使用expo-font导入字体时出现dispatcher.useState错误求助
问题分析与解决方案
你的代码存在一个核心错误:React Hook useState被定义在了函数组件外部,这违反了React Hook的使用规则,直接引发了null is not an object" (evaluating 'dispatcher.useState')的报错。
React Hook(如useState、useEffect)必须遵循以下规则:
- 只能在函数组件的顶层调用,不能嵌套在循环、条件或子函数中
- 只能在React函数组件或自定义Hook内部调用,不能在普通JS函数或组件外部使用
你代码里的const [fontState, setFontState] = React.useState(false);写在了token组件外部,这是不允许的,所以触发了错误。
修正后的代码
import { NavigationContainer, useNavigation } from '@react-navigation/native'; import { FontAwesome } from '@expo/vector-icons'; import { MaterialCommunityIcons } from '@expo/vector-icons'; import {createStackNavigator} from '@react-navigation/stack'; import { AuthContext } from "./context"; import BottomTabNavigator from "./navigation/tabsNav"; import * as firebase from "firebase"; import Myapp from './instanceFirebase'; import AuthStackScreen from './navigation/authStack'; import { ActivityIndicator } from 'react-native' import FlashMessage from "react-native-flash-message"; import * as Font from 'expo-font'; const instanceFirebase = Myapp; import "firebase/functions"; import "firebase/firestore"; const MainStack = createStackNavigator(); const MainStackScreen = () => { return( <MainStack.Navigator initialRouteName="mainPage" > <MainStack.Screen name="mainPage" component={BottomTabNavigator} /> </MainStack.Navigator> ) } const RootStack = createStackNavigator(); const RootStackScreen = ({ userToken }) => ( <RootStack.Navigator headerMode="none"> {userToken ? ( <RootStack.Screen name="App" component={MainStackScreen} /> ) : ( <RootStack.Screen headerMode="none" name="Authstack" component={AuthStackScreen} options={{ animationEnabled: false }} /> )} </RootStack.Navigator> ); export default function token() { // 将fontState移到组件内部定义 const [userToken, setUserToken] = React.useState(null); const [fontState, setFontState] = React.useState(false); const Context = { instanceFirebase: instanceFirebase, signOut: () => { setUserToken(null); }, signIn:() => { setUserToken(true); } } React.useEffect(() => { const fetchFont = async () => { await Font.loadAsync({ Jost: require('./assets/fonts/Jost-Regular.ttf'), Jost_black: require('./assets/fonts/Jost-Black.ttf') }) setFontState(true) } fetchFont() firebase.auth().onAuthStateChanged(user => { if(user){ setUserToken(true) } else { setUserToken(null) } }) }, []) if (!fontState) { return <ActivityIndicator /> } else { return ( <AuthContext.Provider value={instanceFirebase}> <NavigationContainer> <RootStackScreen userToken={userToken} /> <FlashMessage position="top" style={{zIndex:99, flex:1, marginTop:30}}/> </NavigationContainer> </AuthContext.Provider> ) } }
额外提醒
- 确认
expo-font已正确安装,可通过expo install expo-font命令确保安装完成 - 字体文件路径
./assets/fonts/需与项目实际路径匹配,避免出现字体找不到的问题
内容的提问来源于stack exchange,提问作者xenurs
相关产品推荐
相关产品推荐

