首页 > 解决方案 > 反应钩子/渲染困难

问题描述

我正在使用带有 typescript 和非常严格的 eslint 配置的 next.js。我对你将如何解决这个问题很感兴趣。

用例:我想在客户端获取数据。只要数据在那里,我就想显示它。相当容易。

现在的问题。

如果我将 useEffectHook 放在if(!data)块上方,我会得到“TypeError:filterVaccinationsBy 不是函数”

如果我在块下使用我的 useEffectHook,if(!data)我会得到“错误:渲染的钩子比上一次渲染期间更多。”

你如何解决这些问题?

谢谢!!

    const MyPage: any = (props: { AuthUserInfo: any }) => {
  const [vaccinationList, setVaccinationList] = useState<
    IVaccination[] | undefined
  >(undefined);
  const [filter, setFilter] = useState<
    "noFilter" | "travel" | "children" | "gratis" | "combination"
  >("noFilter");

  const { data, error } = useRequest<Vaccinations>(
    VACCINATIONS_QUERY,
    (query: any) => graphQLClient.request<Vaccinations>(query)
  );

  const changeFilterOrder = (vaccinations: IVaccination[] | undefined) => {
    if (filterOrder === "alphabetical") {
      console.log("in alphabetical filtering");

      const alphabeticalOrder = vaccinations?.sort((a, b) =>
        a.name.localeCompare(b.name)
      );
      return alphabeticalOrder;
    }
    if (filterOrder === "chronological") {
      console.log("in chronological filtering");
      const chronologicalOrder = _.sortBy(vaccinations, [
        function (vacc) {
          return vacc.vacc_start_weeks;
        },
      ]);
      return chronologicalOrder;
    }
  };

  useEffect(() => {
    filterVaccinationsBy("noFilter");
  }, []);

  if (!data) {
    return <p>Loading data...</p>;
  }

  if (error) {
    return <p>Error: {JSON.stringify(error)}</p>;
  }
  const { multivaccination, vaccination } = data;

  const mergedList = vaccination.map(
    ({
      id,
      name,
      description,
      vacc_start_weeks,
      vacc_start_text,
      vaccination_vaccination_plan,
    }) => ({
      id,
      name,
      description,
      vacc_start_weeks,
      vacc_start_text,
      vaccination_vaccination_plan,
      multivaccinationByMultivaccination: multivaccination
        .filter((multivacc) => multivacc.parent_id === id)
        .map(({ vaccinations }) => vaccinations),
    })
  );

  const filterVaccinationsBy = (filterBy: string) => {
    if (filterBy === "travel") {
      setFilter("travel");
      const travelVaccinations = mergedList.filter(
        (vacc: IVaccination) =>
          vacc.vaccination_vaccination_plan[0]?.vaccination_plan &&
          vacc.vaccination_vaccination_plan[0]?.vaccination_plan.target_group?.includes(
            "travel"
          )
      );
      const correctOrder = changeFilterOrder(travelVaccinations);
      setVaccinationList(correctOrder);
    }
    if (filterBy === "gratis") {
      setFilter("gratis");
      const gratisVaccinations = mergedList.filter(
        (vacc: IVaccination) =>
          vacc.vaccination_vaccination_plan[0].vaccination_plan?.dose1_price ===
          0
      );
      const correctOrder = changeFilterOrder(gratisVaccinations);
      setVaccinationList(correctOrder);
    }
    if (filterBy === "children") {
      setFilter("children");
      const childrenVaccinations = mergedList.filter(
        (vacc: IVaccination) =>
          vacc.vaccination_vaccination_plan[0].vaccination_plan &&
          vacc.vaccination_vaccination_plan[0].vaccination_plan.target_group?.includes(
            "children"
          )
      );
      const correctOrder = changeFilterOrder(childrenVaccinations);
      setVaccinationList(correctOrder);
    }
    if (filterBy === "combination") {
      setFilter("combination");
      const combinationVaccinations = mergedList.filter(
        (vacc: IVaccination) =>
          vacc.multivaccinationByMultivaccination.length > 0
      );
      const correctOrder = changeFilterOrder(combinationVaccinations);
      setVaccinationList(correctOrder);
    }
    if (filterBy === "noFilter") {
      setFilter("noFilter");
      const correctOrder = changeFilterOrder(mergedList);
      console.log("1");
      setVaccinationList(correctOrder);
      console.log("2");
    }
  };

  return (<p>Hey beautiful<p> )

标签: reactjstypescriptreact-hooks

解决方案


您的 useEffect 不能在您的 if(!data) 下,因为您的功能组件将在该点返回并且永远不会调用 useEffect。反应文档比我解释得更好,但你不能做条件挂钩!必须始终调用钩子!

我认为您得到“TypeError:filterVaccinationsBy 不是函数”,因为调用时未定义 filterVaccinationsBy。将函数声明放在 useEffect 上方,或将其转换为非箭头/标准函数。


推荐阅读