Nil*_*r F 3 reactjs react-native react-navigation expo
我正在开发一个带有 bare expo 和 React Native 的项目。我已经在我的项目中实施了 firebase。登录和注册工作正常。我创建了一个身份验证检查,以便在用户登录时将其发送到另一个页面。尽管在尝试将用户发送到另一个页面时收到以下错误:

这是我的 App.tsx:
import React, { useEffect, useState } from 'react';
import { StatusBar } from 'expo-status-bar';
import { ThemeProvider } from 'styled-components';
import {
useFonts,
Poppins_400Regular,
Poppins_500Medium,
Poppins_700Bold
} from '@expo-google-fonts/poppins';
import AppLoading from 'expo-app-loading';
import theme from './src/global/styles/theme';
import { NavigationContainer } from '@react-navigation/native';
import { AppRoutes } from './src/routes/app.routes';
import 'intl';
import 'intl/locale-data/jsonp/pt-BR';
import { SignIn } from './src/screens/SignIn';
import auth, { FirebaseAuthTypes } from '@react-native-firebase/auth';
export default function App() {
const [ fontsLoaded ] = useFonts({
Poppins_400Regular,
Poppins_500Medium,
Poppins_700Bold
});
const [user, setUser] = useState<FirebaseAuthTypes.User | null>(null);
if (!fontsLoaded) {
return <AppLoading />;
}
useEffect(() => {
const subscriber = auth().onAuthStateChanged(setUser);
return subscriber;
}, []);
return (
<ThemeProvider theme={theme}>
<StatusBar style="light"/>
<NavigationContainer>
{ user ? <AppRoutes /> : <SignIn /> }
</NavigationContainer>
</ThemeProvider>
);
}
Run Code Online (Sandbox Code Playgroud)
这是路线代码:
import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Dashboard } from '../screens/Dashboard';
import { Register } from '../screens/Register';
import { useTheme } from 'styled-components';
import { Platform } from 'react-native';
import { MaterialIcons } from '@expo/vector-icons';
import { Summary } from '../screens/Summary';
const { Navigator, Screen } = createBottomTabNavigator();
export function AppRoutes() {
const theme = useTheme();
return (
<Navigator
screenOptions={{
headerShown: false,
tabBarActiveTintColor: theme.colors.orange,
tabBarInactiveTintColor: theme.colors.texts,
tabBarLabelPosition: 'beside-icon',
tabBarStyle: {
height: 88,
paddingVertical: Platform.OS === 'ios' ? 20 : 0
}
}}
>
<Screen
key="Listing"
name="Listing"
component={Dashboard}
options={{
tabBarIcon: (({ size, color }) =>
<MaterialIcons
name="format-list-bulleted"
size={size}
color={color}
/>
)
}}
/>
<Screen
key="Register"
name="Register"
component={Register}
options={{
tabBarIcon: (({ size, color }) =>
<MaterialIcons
name="attach-money"
size={size}
color={color}
/>
)
}}
/>
<Screen
key="Summary"
name="Summary"
component={Summary}
options={{
tabBarIcon: (({ size, color }) =>
<MaterialIcons
name="pie-chart"
size={size}
color={color}
/>
)
}}
/>
</Navigator>
);
}
Run Code Online (Sandbox Code Playgroud)
您的问题来自此块:
\nif (!fontsLoaded) {\n return <AppLoading />;\n}\n\nuseEffect(() => {\n const subscriber = auth().onAuthStateChanged(setUser);\n return subscriber;\n}, []);\nRun Code Online (Sandbox Code Playgroud)\n您在这里有条件地添加一个钩子,因为如果fontsLoaded计算结果为 false,您会更早返回渲染函数,并且useEffect钩子永远不会在第一次渲染时运行。但是,在后续尝试中,可能会加载字体,这会导致呈现不同数量的挂钩:因此会出现错误。
基于react自己的“hooks规则”指南,强调我自己的:
\n\n\n不要\xe2\x80\x99t 在循环、条件或嵌套函数内调用 Hook。相反,在任何早期返回之前,始终在 React 函数的顶层使用 Hooks。通过遵循此规则,您可以确保每次渲染组件时都以相同的顺序调用 Hook。
\n
要解决此问题,只需确保在任何路径之前定义所有挂钩即可return。在您的情况下,这是通过交换fontsLoaded支票来完成的:
// Define all hooks before any return paths!\nuseEffect(() => {\n const subscriber = auth().onAuthStateChanged(setUser);\n return subscriber;\n}, []);\n\n\nif (!fontsLoaded) {\n return <AppLoading />;\n}\n\nreturn (\n <ThemeProvider theme={theme}>\n <StatusBar style="light"/>\n <NavigationContainer>\n { user ? <AppRoutes /> : <SignIn /> }\n </NavigationContainer> \n </ThemeProvider>\n);\nRun Code Online (Sandbox Code Playgroud)\n当然,有时很难捕获这样的错误,尤其是在重型/复杂的组件中。如果您使用 eslint,则有一个名为 eslint 的插件eslint-plugin-react-hook,当发生这种情况时,它会导致 eslint 抛出警告/错误。
| 归档时间: |
|
| 查看次数: |
7651 次 |
| 最近记录: |