1

const [resourceType, setResourceType] = useState("posts");
const [data, setData] = useState("");
useEffect(() => {
   console.log("use effects called: " + resourceType);
   fetch(`https://jsonplaceholder.typicode.com/${resourceType}`)
     .then((result) => {
         return result.json().then((data) => {
             return {
                 data: data,
                 response: result.status,
             };
         });
         //JSON.parse(result);
     })
     .then((data) => {
         console.log("here");
         setData(JSON.stringify(data));
         console.log(data);
     });
});   
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

I have the above code that is fetching dummy data from JSON placeholder URL and then updating the data variable (setData(JSON.stringify(data))). My question is, this implementation should go into an infinite loop as per my understanding of useEffect and useState react hook. Here is what I think should happen, the page renders it calls useEffect it updates data variable which will cause re-render of the component which should again call useEffect hence re-rending the component and the cycle goes on. But this is not happening and the useEffect is called only twice. Why is this happening?

1
  • 1
    If it rerenders just twice probably your fetch is throwing an exception after a couple of trials and you are not catching the error. Add a .catch() block. Commented Apr 10, 2022 at 0:35

2 Answers 2

2

The data is the same the second time you call setData, so:

  • react doesn’t re-render your component, so
  • the effect doesn’t run, hence
  • no infinite loop.

You’d probably see an infinite loop if you weren’t stringifying the data.

Sign up to request clarification or add additional context in comments.

2 Comments

yes if I don't stringify the data (setData(data)) and use the stringified version of it in the <p> tag (<p>{JSON.stringify(data)}</p>) it in-fact goes into a never ending loop. So, is it safe to say that the useState will not re-render the component if the data it receives is the same the next time (assuming a use case like this )?
That’s how React works but I’d avoid writing code that’s dependent on that assumption.
-1

You need to pass the data object as the dependency array to useEffect()

useEffect(() => {
   ...your code
}, [data]);

1 Comment

This doesn't answer the question as to why OPs code doesn't end up in an infinite loop. The data state also isn't being used in the useEffect(), so it doesn't make much sense to pass it as a dependency. (note that data is coming from the callbacks, not the outside data scope variable)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.