将钩子错误的顺序从上下文更改为 useEffect

时间:2021-04-19 15:41:14

标签: reactjs react-native react-hooks

错误警告:React 检测到 AuthPage 调用的 Hook 顺序发生了变化。如果不修复,这将导致错误和错误。有关更多信息,请阅读 Hooks 规则:https://reactjs.org/link/rules-of-hooks

<头>
上次渲染 下一个渲染
useContext useContext
useContext useContext
useState useState
使用效果 使用效果
useContext 使用效果

代码:

import React, { useContext, useEffect, useState } from 'react';
import { Keyboard } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { getCredentials } from '../util/Storage';
import { OrderContext } from '../OrderContext';
import { UserContext } from '../UserContext';

const AuthPage = ({ navigation }) => {
  const userContext = useContext(UserContext);
  const orderContext = useContext(OrderContext);
  const [isKeyboardVisible, setKeyboardVisibile] = useState(false);
  useEffect(() => {
    const getCreds = async () => {
      const c = await getCredentials();
      if (c) {
        navigation.replace('Home' : 'StartWizard');
      }
    };
    getCreds();
  }, []);

  const keyboardDidShow = () => {
    setKeyboardVisibile(true);
  };

  const keyboardDidHide = () => {
    setKeyboardVisibile(false);
  };

  useEffect(() => {
    Keyboard.addListener('keyboardDidShow', keyboardDidShow);
    Keyboard.addListener('keyboardDidHide', keyboardDidHide);

    return () => {
      Keyboard.removeListener('keyboardDidShow', keyboardDidShow);
      Keyboard.removeListener('keyboardDidHide', keyboardDidHide);
    };
  }, []);

  if (!global.navigation) {
    global.navigation = useNavigation();
  }

  return (
    <AuthView ... />
      }}
    />
  );
};

const Auth = ({ navigation }) => <AuthPage navigation={navigation} />;
export default Auth;

为什么订单会发生变化,我该如何纠正这种行为?

2 个答案:

答案 0 :(得分:0)

  if (!global.navigation) {
    global.navigation = useNavigation();
  }

永远不要有条件地调用钩子。 Its a rule of hooks

答案 1 :(得分:0)

React 总是期望调用相同的钩子,无论你的变量有什么值。

在这种情况下,你有条件地调用 useNavigation() 钩子,这完全搞砸了 React 想要的东西。

要修复它,只需将钩子返回的值存储在一个临时变量中:

const currentNavigation = useNavigation();
if (!global.navigation) {
    global.navigation = currentNavigation;
}

或无条件覆盖 global.navigation(如果没有问题)

global.navigation = useNavigation();

我强烈建议您仔细阅读 rules of hooks,这样您将来就可以避免此类错误。