从 api 获取时反应 useEffect 无限循环
React useEffect Infinite loop when fetching from api
我试图将我的获取请求中的数据存储到一个状态中,但即使没有依赖性,它也会无限循环。当我删除 div 中的代码时,我过滤掉并映射出数组,它似乎不会无限循环,但我不知道为什么 filtering/mapping 会导致它像那样循环
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>
);
}
如果您使用 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)}>
尝试使用 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块。
大多数情况下,我尝试在 useEffect 内部调用函数,同时在 useEffect 外部对该函数进行编码。它对我有用,试试看。
useEffect(() => {
api();
}, []);
const api = async () => {
await fetch("https://api.hatchways.io/assessment/students")
.then((res) => res.json())
.then((data) => setStudents(data.students));
};
问题是在单击按钮时没有设置箭头功能:<button onClick={() => setIsActive(!isActive)}>
<button onClick={setIsActive(!isActive)}>
这可能是罪魁祸首。你正在改变每一个兰德的状态。您应该将 () => setIsActive(!isActive)
作为 onClick 处理程序传递。
我试图将我的获取请求中的数据存储到一个状态中,但即使没有依赖性,它也会无限循环。当我删除 div 中的代码时,我过滤掉并映射出数组,它似乎不会无限循环,但我不知道为什么 filtering/mapping 会导致它像那样循环
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>
);
}
如果您使用 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)}>
尝试使用 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块。
大多数情况下,我尝试在 useEffect 内部调用函数,同时在 useEffect 外部对该函数进行编码。它对我有用,试试看。
useEffect(() => {
api();
}, []);
const api = async () => {
await fetch("https://api.hatchways.io/assessment/students")
.then((res) => res.json())
.then((data) => setStudents(data.students));
};
问题是在单击按钮时没有设置箭头功能:<button onClick={() => setIsActive(!isActive)}>
<button onClick={setIsActive(!isActive)}>
这可能是罪魁祸首。你正在改变每一个兰德的状态。您应该将 () => setIsActive(!isActive)
作为 onClick 处理程序传递。