This a specific sort of problem with a specific sort of solution. So far, so vague.
In Javascript/React we often run into asynchronous behavior - that is, certain parts of our code run before others. This could be due to a number of reasons, such as a lag in the code running and state being set and the nature of fetch requests/promises.
There's ways we can handle this.
One way is to use the useEffect hook. Whatever code is contained within the useEffect hook will run upon page render AND when a change is made to whatever is in the dependency array.
This can be utilized very powerfully. The primary instance I have run into is when some user action happens and triggers a POST or PATCH request, the data displayed on the frontend may need to be updated. If we put the state, where we stored our data, in the dependency array, it will get triggered and run again, thus populating our frontend with new, updated data.
But sometimes, even still, there is a lag in the setting of our state(s) (which is storing some of our data and being used to display it on the frontend) on being set and the code running. This can be bad. For example, if we want to map over our state, which should be an array of data, but it's not yet set to said array, the app is going to stop working. It will error out and say, something like, "restaurants.map is Undefined." which, in English, means, "We can't map over that! It's not an array!" And it's not, at least not for another second or two.
Even with useEffect, this async behavior can be a bummer.
While it wasn't the "most correct" or "efficient" move, I even have used setTimeOut() to account for the latency of state being set.
Here, I'm using the .find() method, which does the same sort of thing as .map(), iterates through an array, and would return the same aforementioned error if its object is, indeed, not an array. The setTimout() is an asynchronous function, so it's kind of like fighting fire with fire. Its first argument is the code you want to run and its second argument is the number of milliseconds you want it to wait to execute upon page render.
The other example I would like to share is one which uses a styled component from MaterialUi's library, CircularProgress. MaterialUi Docs are mostly great and provide a clear walkthrough if you are interested in implementing some built-in styles to you React project. CircularProgress is a loading circle, more or less.
In my example, "user" is a state that we need for the rest of the code to run, but if we don't have a user yet, due to whatever reason, another error or simply asynchronous behavior, hopefully the latter, because if it is, this might help.
Here, we are using conditional logic. If we don't yet have a truthy-valued "user" state, we will get a loading icon returned. Then, when there is a user, the rest of the code will run!
State can be tricky and you may still run into issues.
Another, but more complex, tool to use is a newer part of React, async/await. This involves creating an "async function" rather than a regular ole "function". I'm not going to go into it because that's a blog post all on it's own.
Top comments (0)