从 api 获取时反应 useEffect 无限循环
Posted
技术标签:
【中文标题】从 api 获取时反应 useEffect 无限循环【英文标题】:React useEffect Infinite loop when fetching from api 【发布时间】:2022-01-12 09:11:54 【问题描述】:我正在尝试将我的 fetch 请求中的数据存储到一个状态中,但即使没有依赖关系,它最终也会无限循环。当我删除 div 中的代码时,我过滤掉并映射出数组,它似乎没有无限循环,但我不知道为什么过滤/映射会导致它像那样循环
function App()
const [searchTerm, setSearchTerm] = useState("");
const [students, setStudents] = useState([]);
const [isActive, setIsActive] = useState(false);
const average = (array) =>
return array.reduce((a, b) => a + parseFloat(b), 0) / array.length;
;
useEffect(() =>
const api = async () =>
await fetch("https://api.hatchways.io/assessment/students")
.then((res) => res.json())
.then((data) => setStudents(data.students));
;
api();
, []);
return (
<div className='bg-gray-300 h-screen flex items-center justify-center'>
students
.filter((student) =>
if (searchTerm === "")
return student;
else if (
student.firstName
.toLowerCase()
.includes(searchTerm.toLowerCase()) ||
student.lastName.toLowerCase().includes(searchTerm.toLowerCase())
)
return student;
)
.map((student, i) => (
<div
key=i
className='flex items-center space-x-8 px-8 py-3 border-b'>
<div className='flex items-start w-full space-x-7'>
<div className='border overflow-hidden rounded-full'>
<img
className='w-24 h-24 bg-contain'
src=student?.pic
alt='student school portrait'
/>
</div>
<div className='flex flex-col justify-between space-y-4 w-full'>
<div className='flex items-center justify-between'>
<h1 className='font-bold text-5xl'>
student?.firstName student?.lastName
</h1>
<button onClick=setIsActive(!isActive)>
isActive ? (
<AiOutlinePlus className='h-7 w-7' />
) : (
<AiOutlineMinus className='h-7 w-7' />
)
</button>
</div>
<div className='pl-3'>
<p>Email: student?.email</p>
<p>Company: student?.company</p>
<p>Skill: student?.skill</p>
<p>Average: average(student?.grades).toFixed(2)%</p>
</div>
</div>
</div>
</div>
))
</div>
);
【问题讨论】:
【参考方案1】:如果您使用async/await
,则无需链接.then()
。
尝试将您的 useEffect 更新为:
useEffect(() =>
api();
, []);
const api = async () =>
let res = await fetch("https://api.hatchways.io/assessment/students");
let data = await res.json();
setStudents(data.students)
;
另外,在按钮单击处理程序中使用箭头函数:
<button onClick=()=>setIsActive(!isActive)>
【讨论】:
刚刚尝试使用它,但仍然没有运气,由于某种原因,我在 useEffect 中使用 setStudents 时遇到了问题 导入是正确的,我也有这个,还有 useState,我的学生占位符状态是一个空数组 @StevenSmith 请尝试更新的答案,第一个代码。 我刚试了一下,还是会无限重复。当我出于某种原因在 useEffect 中设置了 setStudents 时,它不喜欢它。 @StevenSmith 将函数移到 useEffect 之外【参考方案2】:尝试使用async-await
语法
useEffect(() =>
const fetchData = async () =>
const response = await fetch(
"https://api.hatchways.io/assessment/students"
);
const result = await response.json();
console.log("res", result);
;
fetchData();
, []);
如果你想处理错误,你需要添加try catch块。
【讨论】:
我的代码已经实现了 async/await【参考方案3】:大多数情况下,我尝试在 useEffect 内部调用函数,而在 useEffect 外部调用该函数。它对我有用,试试吧。
useEffect(() =>
api();
, []);
const api = async () =>
await fetch("https://api.hatchways.io/assessment/students")
.then((res) => res.json())
.then((data) => setStudents(data.students));
;
【讨论】:
我刚试过这个,但我在 .then 链之后执行 setStudents(data) 仍然存在问题【参考方案4】:问题是没有在点击按钮时设置箭头功能:<button onClick=() => setIsActive(!isActive)>
【讨论】:
【参考方案5】:<button onClick=setIsActive(!isActive)>
这可能是罪魁祸首。您正在更改每个 rander 中的状态。您应该将 () => setIsActive(!isActive)
作为 onClick 处理程序传递。
【讨论】:
以上是关于从 api 获取时反应 useEffect 无限循环的主要内容,如果未能解决你的问题,请参考以下文章
React useEffect() 无限重新渲染以获取所有尽管有依赖关系
在使用 graphql 的 useQuery 获取的数据更新 useEffect 钩子内的状态变量时防止无限渲染