I was trying to replicate a personal project to set a Spinner loader while the data fetch is being load but I got another error before.
I was reading in other questions like this one, that in order to avoid a useEffect()
infinite loop I have to add an empty array to the end, but still it doesn't work.
This is my code, it just re-renders infinitely despite the empty array added.
src/ponents/Users.js
import React, { useState, useEffect, useContext } from "react";
import GlobalContext from "../context/Global/context";
export default () => {
const context = useContext(GlobalContext);
const [users, setUsers] = useState([]);
async function getUsers() {
context.setLoading(true);
const response = await fetch("");
if (response.ok) {
context.setLoading(false);
const data = await response.json();
setUsers(data);
} else {
console.error('Fetch error');
}
}
useEffect(() => {
getUsers();
}, []);
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
This is the non-working Sandbox, I am not sure why this is happening, any ments are appreciated.
I was trying to replicate a personal project to set a Spinner loader while the data fetch is being load but I got another error before.
I was reading in other questions like this one, that in order to avoid a useEffect()
infinite loop I have to add an empty array to the end, but still it doesn't work.
This is my code, it just re-renders infinitely despite the empty array added.
src/ponents/Users.js
import React, { useState, useEffect, useContext } from "react";
import GlobalContext from "../context/Global/context";
export default () => {
const context = useContext(GlobalContext);
const [users, setUsers] = useState([]);
async function getUsers() {
context.setLoading(true);
const response = await fetch("https://jsonplaceholder.typicode./users");
if (response.ok) {
context.setLoading(false);
const data = await response.json();
setUsers(data);
} else {
console.error('Fetch error');
}
}
useEffect(() => {
getUsers();
}, []);
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
};
This is the non-working Sandbox, I am not sure why this is happening, any ments are appreciated.
Share Improve this question edited Dec 23, 2019 at 4:04 Maramal asked Dec 23, 2019 at 3:43 MaramalMaramal 3,4749 gold badges59 silver badges102 bronze badges 2- Hi Maramal, check my solution and let me know if that helps. – ravibagul91 Commented Dec 23, 2019 at 3:56
- Does this answer your question? React hook useEffect runs continuously forever/infinite loop – Yangshun Tay Commented Apr 12, 2020 at 16:30
2 Answers
Reset to default 7The problem is you keep mounting and then umounting the Users ponent. The <App>
renders, and loading is false, so it renders <Users>
. Since Users rendered its effect gets run which immediately sets loading to true.
Since loading is now true, <App>
rerenders, and no longer has a <Users>
ponent. You have no teardown logic in your effect, so the fetch continues, and when it's done, it sets loading to false and sets users to the data it got. Trying to set users actually results in this error in the console, which points out that Users is unmounted:
proxyConsole.js:64 Warning: Can't perform a React state update on an unmounted ponent. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.
in _default (at App.js:25)
And now that loading has been set to false, the process repeats.
The solution to this is to have the data loading be in a ponent that stays mounted. Either change App to not unmount Users, or move the fetching up to App and pass the data as a prop.
I think the issue is because of
context.setLoading(false);
just remove this line from your getUsers
function and add a separate useEffect
hook.
useEffect(() => {
context.setLoading(false);
}, [users]) //Run's only when users get changed
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745342855a4623408.html
评论列表(0条)