【发布时间】:2021-12-26 13:30:43
【问题描述】:
我的 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 钩子之上。
【问题讨论】:
-
fetchRecipes是做什么的? -
我添加了
fetchRecipes函数的小描述。如果您需要了解更多信息,请告诉我...非常感谢! -
顺便说一下,我没有在这个项目中使用 Redux Toolkit,只是让你知道
-
请分享
fetchRecipes的实际代码。我打赌你在那里使用了一个钩子,因此违反了钩子的规则。题外话,你真的应该使用 Redux Toolkit。多年来,它是每个 Redux 代码的官方推荐。 -
其实我在
fetchRecipes中使用了一个钩子!我会马上分享它的代码!
标签: reactjs redux react-hooks graphql apollo