reactjs - 反应钩子/渲染困难
问题描述
我正在使用带有 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> )
解决方案
您的 useEffect 不能在您的 if(!data) 下,因为您的功能组件将在该点返回并且永远不会调用 useEffect。反应文档比我解释得更好,但你不能做条件挂钩!必须始终调用钩子!
我认为您得到“TypeError:filterVaccinationsBy 不是函数”,因为调用时未定义 filterVaccinationsBy。将函数声明放在 useEffect 上方,或将其转换为非箭头/标准函数。
推荐阅读
- javascript - 正则表达式:排除除数字、空格、加号和句点之外的所有内容
- excel - 在用户窗体的列表框中选择特定项目时,必须将另一个文本框中的文本复制到表格单元格
- sql - 如何在 SQL Server 中转换一些记录
- c++ - 通过引用使用 const int 创建静态数组
- docker - 将虚拟主机迁移到 Docker 容器有哪些优势?
- bash - F in * 的脚本
- git - `git reset -q` 可以等效于一些没有`-q` 的`git reset` 命令吗?
- docker - 为具有 Windows 主机的 Linux docker 容器上的卷配置用户和组
- google-tag-manager - 如何注册 GTM Google Analytics 事件链接到锚点(#)?
- r - How to apply a table to several columns with data.table?