Impossible states in React

preview_player
Показать описание
Avoid an impossible state by deriving #react #reactjs #reactjsdeveloper #programming #progammer #frontend #devtok #coding #code #codetok
Рекомендации по теме
Комментарии
Автор

I thought they would be batched and updated together

abdelfadeel
Автор

I like this from a maintainability perspective, but the "impossible state" argument does not apply after React 18 (since automatic batching came in)

baldcoder_
Автор

This is not correct, the rerender will happen after the 2 calls, you can test that by putting a log in your code to count rerenders.

julienvanbeveren
Автор

If the state updates were called synchronously:
setState(...);
setState(...);
setState(...);

They'll be batched so it's not an impossible state because the state update in catch and finally are called synchronously. But if you somehow added an async operation in the middle, like setting a state -> calling something async -> setting a state.

Or as an example with your example:
catch {
setError(...);
await something(); // just an example
} finally {
setIsLoading(...);
}
Then it won't be batched anymore, and will be the impossible state that you're describing.

nevz
Автор

That's why we should use fetching libraries like SWR or RTKQuery these libraries allows us to avoid using states in our components ❤

Solo_playz
Автор

You can also prevent the impossible state by using !loading && error <p>{error}</p>
and !loading && !error <p>Successful</p>

samuelodiase-omoighe
Автор

I'm confused here, what is the problem we are facing here?

what's wrong in having error and setLoading true for a split second? I mean: error is loaded into state -> Loading set to false -> now error is displayed?

sainathpoojaryy
Автор

Looks like a tanstack query model, but how we are going to reset it agian to idle state ?

shubhankarmaheshwari
Автор

Since automatic batching this might not be the case.
BUT its still seems a better way to use one state than two for isLoading and isError. So thanks!!

slippery-sukuna
Автор

If I'm not mistaking, setError and setIsLoading are synchronous operations, thus JS will execute at least those two operations back to back without giving the opportunity for react to re-render this component (a browser render won't even be possible between those two calls).

As @nevz9851 pointed out, this would only be actually an issue if you were to call an asynchronous function between the two setStates, in which case JS will pause the execution of this function, allowing other code to run (and possibly re-render react components), until the browser informs the JS runtime that the async function is done so it can call the second setState.

kehto
Автор

Wow, I didn't know this before ❤️❤️

uzairahmed
Автор

That's a great idea. Why I haven't thought about it so far?

prakashd
Автор

maybe the dev want to catch the e.message

omnilothar
Автор

nice way, i dont know why this wasnt implemented before

akshaysrivastava
Автор

The render will happen after both values are updated

ankitsuda
Автор

So how do you get the error message? You set the status to error.message and if it doesnt equal loading or idle it's an error? This doesnt seem like a good implementation.

matthewbeardsley
Автор

Its a “sync” function, the render will not happen until the function execution has completed.
Read about the event loop to understand how it works.

aa-mw
Автор

That would be cool, if JavaScript had enums where you could track the states it could be in. But imagine someone who’s never seen the code before trying to work out what the possible states are.

yourgflikesit
Автор

This example confuses me. I would think set state calls would both take place effectively at the same time. So, setLoading to true and then to false within the same useffect would justbl tigger setLoading to true once the entire useEffect has executed

alexandersnow
Автор

so set loading false in both catch and finally is bad ?

ThanHtutZaw