繁体   English   中英

无效的钩子调用。 Hooks 只能在 react 函数组件内部使用... useEffect, redux

[英]Invalid hook call. Hooks can only be used inside of a react function component... useEffect, redux

我的 React 应用程序遇到了与钩子相关的问题。 使用的技术:React、Redux、Apollo、ChakraUI。

这是困扰我的 React 组件:

import React, { useEffect } from "react";
import { Flex, Container, Heading, Text } from "@chakra-ui/react";
import { connect, useSelector, useDispatch } from "react-redux";
import { State } from "../state/store";
import { fetchRecipes } from "../state/recipe/actions";

interface RecipesListProps {}

const RecipesList: React.FC<RecipesListProps> = ({}) => {

  const recipes = useSelector<State>(
    (state) => state.recipe.recipes
  ) as State["recipe"]["recipes"];

  const loading = useSelector<State>(
    (state) => state.recipe.loading
  ) as State["recipe"]["loading"];

  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(fetchRecipes());
  }, []);

  if (loading) {
    return <h1>Loading....</h1>;
  }
  return (
    <Flex
      m="auto"
      mt="5rem"
      w="50%"
      direction="column"
      justifyContent="center"
      alignItems="center"
    >
      <Heading>Your Recipes</Heading>
      <Flex mt="2rem" direction="column" w="100%" padding="0" gridGap="2rem">
        {recipes &&
          recipes.map((recipe) => (
            <Container
              key={recipe.id}
              bg="orange.100"
              borderRadius="0.2rem"
              padding="1rem"
              maxW="100%"
            >
              <Text fontSize="xl" fontWeight="bold">
                {recipe.title}
              </Text>
              <Text>{recipe.description}</Text>
            </Container>
          ))}
      </Flex>
    </Flex>
  );
};

export default RecipesList;

注意useEffect()钩子的使用。 这是我得到的错误:


Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app

我很确定我违反了规则编号 2,即我违反了 Hooks 规则。 一旦我从组件中取出useEffect()调用,它就不会抛出错误。

有人可以就我做错了什么提供一些指导吗? 谢谢。

编辑:

fetchRecipes函数是一个 Redux thunk 函数,用于从 graphql 服务器获取配方

更新:

我一直在破解这个问题的解决方案。 我用console.log("hello world")替换了dispatch(fetchRecipes())调用,它工作得很好!

这让我大吃一惊! 这是fetchRecipes函数的问题吗?

编辑:

这是fetchRecipes函数的代码:

export const fetchRecipes = () => {
  return (dispatch: Dispatch) => {
    dispatch(fetchRecipesPending());
    const { data } = useRecipesQuery();
    const errors = data?.recipes.errors;
    const recipes = data?.recipes.recipes;
    if (errors?.length) {
      dispatch(fetchRecipesFailure(errors));
    } else {
      dispatch(fetchRecipesSuccess(recipes));
    }
  };
};

useRecipesQuery是一个使用graphql-codegen库自动生成的自定义钩子。 它建立在来自@apollo/client库的useQuery钩子上。

您的useEffect需要稍微重写一下。 您正在调度函数fetchRecipes ,它本身就是一个钩子,但调度的东西应该是一个简单的“动作”(这里使用 Redux 术语)。 所以我想我们可以通过分解你的 fetchRecipes fn 来解决这个问题。

组件的一个片段现在看起来像下面这样:

const { data } = useRecipesQuery();

useEffect(() => {
  if (!data) {
    dispatch(fetchRecipesPending()) // I only assume you fetch on render
  }
  if (data?.recipes?.errors) {
    dispatch(fetchRecipesFailure(data?.recipes.errors)
  }
  if (data?.recipes?.recipes) {
    dispatch(fetchRecipesSuccess(data?.recipes?.recipes)))
  }
}, [data]);

现在它应该没问题并且更具可读性。 无论哪种方式,正如一些人已经建议的那样,我会考虑使用一些更标准化的方式,例如使用 Redux w/Thunks 或 Sagas,或者甚至更好 - 我看到您可能正在执行 GQL 查询 - 如果是这样,只需使用一个钩子它并使用 Apollo Client 处理数据。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM