简体   繁体   English

React Hooks + Mobx => 无效的钩子调用。 Hooks 只能在函数组件内部调用

[英]React Hooks + Mobx => Invalid hook call. Hooks can only be called inside of the body of a function component

I have a React Native App, Here i use mobx ("mobx-react": "^6.1.8") and react hooks.我有一个 React Native 应用程序,在这里我使用 mobx ("mobx-react": "^6.1.8") 和 react hooks。

i get the error: Invalid hook call.我收到错误:无效的钩子调用。 Hooks can only be called inside of the body of a function component Hooks 只能在函数组件内部调用

Stores index.js存储 index.js

import { useContext } from "react";
import UserStore from "./UserStore";
import SettingsStore from "./SettingsStore";


const useStore = () => {
  return {
    UserStore: useContext(UserStore),
    SettingsStore: useContext(SettingsStore),
  };
};

export default useStore;

helper.js OLD helper.js 旧

    import React from "react";
    import useStores from "../stores";

    export const useLoadAsyncProfileDependencies = userID => {
  const { ExamsStore, UserStore, CTAStore, AnswersStore } = useStores();
  const [user, setUser] = useState({});
  const [ctas, setCtas] = useState([]);
  const [answers, setAnswers] = useState([]);

  useEffect(() => {
    if (userID) {
      (async () => {
        const user = await UserStore.initUser();
        UserStore.user = user;
        setUser(user);
      })();
      (async () => {
        const ctas = await CTAStore.getAllCTAS(userID);
        CTAStore.ctas = ctas;
        setCtas(ctas);
      })();
      (async () => {
        const answers = await AnswersStore.getAllAnswers(userID);
        UserStore.user.answers = answers.items;
        AnswersStore.answers = answers.items;
        ExamsStore.initExams(answers.items);
        setAnswers(answers.items);
      })();
    }
  }, [userID]);
};

Screen屏幕

import React, { useEffect, useState, useRef } from "react";
import {
  View,
  Dimensions,
  SafeAreaView,
  ScrollView,
  StyleSheet
} from "react-native";
import {
  widthPercentageToDP as wp,
  heightPercentageToDP as hp
} from "react-native-responsive-screen";

import { observer } from "mobx-react";
import useStores from "../../stores";
import { useLoadAsyncProfileDependencies } from "../../helper/app";
const windowWidth = Dimensions.get("window").width;

export default observer(({ navigation }) => {
  const {
    UserStore,
    ExamsStore,
    CTAStore,
    InternetConnectionStore
  } = useStores();
  const scrollViewRef = useRef();

  const [currentSlide, setCurrentSlide] = useState(0);

  useEffect(() => {
    if (InternetConnectionStore.isOffline) {
      return;
    }
    Tracking.trackEvent("opensScreen", { name: "Challenges" });
    useLoadAsyncProfileDependencies(UserStore.userID);
  }, []);

  React.useEffect(() => {
    const unsubscribe = navigation.addListener("focus", () => {
      CTAStore.popBadget(BadgetNames.ChallengesTab);
    });
    return unsubscribe;
  }, [navigation]);

  async function refresh() {
    const user = await UserStore.initUser(); //wird das gebarucht?
    useLoadAsyncProfileDependencies(UserStore.userID);
    if (user) {
      InternetConnectionStore.isOffline = false;
    }
  }

  const name = UserStore.name;

  return (
    <SafeAreaView style={styles.container} forceInset={{ top: "always" }}>

    </SafeAreaView>
  );
});

so now, when i call the useLoadAsyncProfileDependencies function, i get this error.所以现在,当我调用 useLoadAsyncProfileDependencies 函数时,我收到此错误。

The Problem is that i call useStores in helper.js问题是我在 helper.js 中调用 useStores

so when i pass the Stores from the Screen to the helper it is working.所以当我将 Stores 从屏幕传递给助手时,它正在工作。

export const loadAsyncProfileDependencies = async ({
  ExamsStore,
  UserStore,
  CTAStore,
  AnswersStore
}) => {
  const userID = UserStore.userID;
  if (userID) {
    UserStore.initUser().then(user => {
      UserStore.user = user;
    });
    CTAStore.getAllCTAS(userID).then(ctas => {
      console.log("test", ctas);
      CTAStore.ctas = ctas;
    });
    AnswersStore.getAllAnswers(userID).then(answers => {
      AnswersStore.answers = answers.items;
      ExamsStore.initExams(answers.items);
    });
  }
};

Is there a better way?有没有更好的办法? instead passing the Stores.而是通过商店。 So that i can use this function in functions?这样我就可以在函数中使用这个函数了?

As the error says, you can only use hooks inside the root of a functional component, and your useLoadAsyncProfileDependencies is technically a custom hook so you cant use it inside a class component.正如错误所说,您只能在功能组件的根内使用钩子,而您的useLoadAsyncProfileDependencies从技术useLoadAsyncProfileDependencies是一个自定义钩子,因此您不能在类组件内使用它。

https://reactjs.org/warnings/invalid-hook-call-warning.html https://reactjs.org/warnings/invalid-hook-call-warning.html


EDIT: Well after showing the code for app.js, as mentioned, hook calls can only be done top level from a function component or the root of a custom hook.编辑:正如前面提到的,在显示 app.js 的代码之后,钩子调用只能在函数组件或自定义钩子的根的顶层完成。 You need to rewire your code to use custom hooks.您需要重新连接代码以使用自定义挂钩。

SEE THIS: https://reactjs.org/docs/hooks-rules.html看到这个: https : //reactjs.org/docs/hooks-rules.html

  1. You should return the value for _handleAppStateChange so your useEffect 's the value as a depdendency in your root component would work properly as intended which is should run only if value has changed.您应该返回_handleAppStateChange的值,以便您的useEffect作为根组件中的依赖项的值将按预期正常工作,只有在值更改时才应运行。 You also need to rewrite that as a custom hook so you can call hooks inside.您还需要将其重写为自定义钩子,以便您可以在内部调用钩子。

  2. doTasksEveryTimeWhenAppWillOpenFromBackgorund and doTasksEveryTimeWhenAppGoesToBackgorund should also be written as a custom hook so you can call useLoadAsyncProfileDependencies inside. doTasksEveryTimeWhenAppWillOpenFromBackgorunddoTasksEveryTimeWhenAppGoesToBackgorund也应编写为自定义钩子,以便您可以在内部调用useLoadAsyncProfileDependencies

  3. write those hooks in a functional way so you are isolating specific tasks and chain hooks as you wish without violiating the rules of hooks.以函数式方式编写这些钩子,这样您就可以在不违反钩子规则的情况下根据需要隔离特定任务和链钩子。 Something like this:像这样的东西:

const useGetMyData = (params) => {
    const [data, setData] = useState()

    useEffect(() => {
        (async () => {
            const apiData = await myApiCall(params)
            setData(apiData)
        })()
    }, [params])

    return data
}

Then you can call that custom hook as you wish without violation like:然后您可以根据需要调用该自定义钩子而不会违反,例如:



const useShouldGetData = (should, params) => {
    if (should) {
        return useGetMyData()
    }

    return null
}

const myApp = () => {
    const myData = useShouldGetData(true, {id: 1})

    return (
        <div>
            {JSON.stringify(myData)}
        </div>
    )
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 React Hooks Mobx:无效的钩子调用。 钩子只能在函数组件的主体内部调用 - React Hooks Mobx: invalid hook call. Hooks can only be called inside of the body of a function component 反应钩子错误:无效的钩子调用。 钩子只能在 function 组件的主体内部调用 - React hook Error: Invalid hook call. Hooks can only be called inside of the body of a function component 反应,得到错误:无效的钩子调用。 Hooks 只能在函数组件的主体内部调用 - React, getting Error: Invalid hook call. Hooks can only be called inside of the body of a function component React - 错误:无效的钩子调用。 钩子只能在 function 组件的主体内部调用 - React - Error: Invalid hook call. Hooks can only be called inside of the body of a function component React 和 Easybase - 无效的钩子调用。 钩子只能在 function 组件的主体内部调用 - React and Easybase - Invalid hook call. Hooks can only be called inside of the body of a function component 挂钩调用无效。 挂钩只能在反应聊天应用程序中显示的 function 组件的主体内部调用 - Invalid hook call. Hooks can only be called inside of the body of a function component show in react chat app React Native 错误:无效的钩子调用。 钩子只能在 function 组件的主体内部调用 - React Native Error: Invalid hook call. Hooks can only be called inside of the body of a function component 错误:无效的挂钩调用。 钩子只能在 function 组件的主体内部调用。 通过路由反应 - Error: Invalid hook call. Hooks can only be called inside of the body of a function component. by Routing in react 错误:无效的挂钩调用。 钩子只能在 react-native 中的 function 组件的主体内部调用 - Error: Invalid hook call. Hooks can only be called inside of the body of a function component in react-native 反应无效的钩子调用。 钩子只能在 function 组件的主体内部调用 - React Invalid hook call. Hooks can only be called inside of the body of a function component
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM