javascript - React 检测到 Navigation 调用的 Hooks 的顺序发生了变化

标签 javascript reactjs typescript react-native react-hooks

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

   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)

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

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;

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

最佳答案

查看 rules of hooks

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

修复非常简单:移动 useRef if (authStore.token === undefined) return null; 以上的用法你很好。

关于javascript - React 检测到 Navigation 调用的 Hooks 的顺序发生了变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69102128/

相关文章:

javascript - 如何正确访问JSON数组?

javascript - Bootstrap 下拉菜单未打开,首先单击 React 16

javascript - 如何在javascript中过滤对象子数组的数组和对象子数组的数组

javascript - 在 Typescript 中,方法只能存在于子类中吗?

Angular - @Input 和@Output 与可注入(inject)服务

javascript - 如何针对不同的容器使用javascript方法?

javascript - React redux-saga 如何将 prop 传递给嵌套子级

javascript - 当我们使用 javascript 只允许文本框中的数字时允许使用 tab 键

javascript - Jquery Animate - 使元素只弹跳一次

javascript - material-ui 用 useStyles/jss 覆盖主题