React检测到导航调用的钩子顺序发生了变化



我真的很难弄清楚我的问题在哪里,我最近更改了很多代码,现在我遇到了这个问题

ERROR  Warning: React has detected a change in the order of Hooks called by Navigation. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks
Previous render            Next render
------------------------------------------------------
1. useContext                 useContext
2. undefined                  useRef
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
in Navigation (at App.tsx:96)
in RCTView (at View.js:34)
in View (at createAnimatedComponent.js:217)
in AnimatedComponent (at createAnimatedComponent.js:278)
in AnimatedComponentWrapper (at createAnimatableComponent.js:599)
in withAnimatable(View) (at App.tsx:89)
in App (at mobile/index.js:28)
in HeadlessCheck (at renderApplication.js:47)
in RCTView (at View.js:34)
in View (at AppContainer.js:107)
in RCTView (at View.js:34)
in View (at AppContainer.js:134)
in AppContainer (at renderApplication.js:40)

这大概是指我的导航类,我将在下面分享,我对钩子背后的概念没有特别的了解,这个问题让我很困惑

import * as React from 'react';
import { View } from 'react-native';
import { NavigationContainer, NavigationContainerRef } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { useStore } from '_src/store';
import { logScreenView } from '_utils/analytics';
import { SharedStackParamList } from './shared/SharedStack';
import { getSharedScreens } from './shared/Shared.screens';
import ErrorBoundary from '../components/atoms/ErrorBoundary';
import { modalOptions } from './StackOptions';
import { BLACK } from '_styles/colors';
const SharedStack = createStackNavigator<SharedStackParamList>();
export const Navigation = () => {
const rootStore = useStore();
const { authStore } = rootStore;
if (authStore.token === undefined) return null;
const routeNameRef = React.useRef<string>();
const navigationRef = React.useRef<NavigationContainerRef>();
function onReady() {
routeNameRef.current = navigationRef.current.getCurrentRoute().name;
}
function onStateChange() {
const previousRouteName = routeNameRef?.current;
const currentRouteName = navigationRef?.current?.getCurrentRoute()?.name;
if (previousRouteName !== currentRouteName) {
logScreenView({ screen_name: currentRouteName, screen_class: currentRouteName });
routeNameRef.current = currentRouteName;
}
}
// Return main stack
return (
<View style={{ flex: 1, backgroundColor: BLACK, opacity: 1 }}>
<ErrorBoundary>
<NavigationContainer ref={navigationRef as any} onReady={onReady} onStateChange={onStateChange}>
<SharedStack.Navigator screenOptions={modalOptions} mode="modal">
{getSharedScreens().map(({ name, options, component }, i) => {
// @ts-ignore
return <SharedStack.Screen key={i} name={name} options={options} component={component} />;
})}
</SharedStack.Navigator>
</NavigationContainer>
</ErrorBoundary>
</View>
);
};
export default Navigation;

如果有人能帮助我更好地理解钩子,并帮助我解决这个问题,我将不胜感激。

查看钩子的规则(在旧的React文档页)

钩子总是需要以相同的顺序调用(因此不允许有条件地添加新钩子)。你的代码违反了这条规则,因为你在有条件返回null后使用了useRef钩子。

解决方法很简单:将useRef的用法移到if (authStore.token === undefined) return null;之上,就可以了。

相关内容

最新更新