DEV Community

loading...

Don't be too dependent on useState, useRef is there for you

sakethk
Computer jock, Programmer, Technology enthusiast and Math ❤️ er.
・2 min read

Hello 👋
Hope all are doing good in this pandemic time.

Whenever i am seeing any reactjs code snippets in internet i am noticing the unnecessary usage of useState.

In react updating a state is a very expensive in terms of performance. The main reason is whenever the state updates the component will re-render again.

Here is an small example:
Screenshot 2021-07-24 at 5.36.02 PM.png

In the above code i created a counter using useState when i am incrementing the counter App component is re-rendering again. There if you check the logs Component initialised got printed 4 times (1st time when component initialised and 3 times when i clicked on the + button). It is re-rendering the App component because i am updating the state on click of the + button.

Here we need to use state because our intention is to show the counter value in the document.

Consider the following code 👇🏻
Screenshot 2021-07-24 at 5.51.43 PM.png

Here i am using two state variables one is for value next is to set type of input. Do we really need two state variables 🤔 ?. Actually why don't we try building this component without state ? the reason why i am saying like this is assume if we are building a form has many input fields in that case we need to pass value state to input component from form component if that's the case entire form component will re-render on every keystroke in any input.

Solution

In the second example actually we don't need state. useRef is fine. Check the below code 👇🏻

in the ☝🏻 snippet we are not using state but still we able to achieve what we want without out re-rendering. Even in form use case instead if passing state from form to input we can pass ref it will prevent unnecessary re-renders.

So what i would suggest is whenever you are dealing DOM manipulation like changing class name conditionally or changing any attribute of element etc.. then try to use useRef instead of useState. it will prevent your app from too many re-renders.

Follow me on
Linkedin : https://www.linkedin.com/in/saketh-kowtha/
Twitter : https://twitter.com/sakethkowtha
Github : https://github.com/saketh-kowtha

Discussion (17)

Collapse
lexlohr profile image
Alex Lohr

So basically you're shifting the re-render from react's reconciler to the DOM. If you want to forgo the virtual DOM in order to improve performance, you could also consider a framework like Svelte or SolidJS.

Collapse
jwhenry3 profile image
Justin Henry

I see useRef as a way to do internal state updates without causing a re-render. Something you want to retain without impacting renders. When most of the world has moved to Svelte/Solid, then I think most react devs will be happy to move over, but since the job market is not there for it, it makes it less valuable to an individual engineer to invest in it so fully.

Collapse
lexlohr profile image
Alex Lohr

Here's an issue: react does not guarantee that the nodes it manages stay the exact same. So if something else causes a re-render, you may lose the attribute if it is also managed by react and thus overwritten by the reconciler.

And as I already stated, the DOM of the changed node will re-render anyways, only the virtual DOM will not precede that update.

If your goal is performance, better avoid unnecessary re-rendering of components. Fine-grained updates should be sufficiently performant already - and if they aren't, your problem is either somewhere else or react is not the solution. Maybe Svelte or SolidJS would be a solution in that case - that's all I'm saying - not that everyone should switch.

That being said, the best thing about react is the tooling, which makes for a developer experience unmatched by most other frameworks.

Collapse
sakethkowtha profile image
sakethk Author • Edited

I am not saying Don't use state. My intention is to reduce the usage of useState where ever it is unnecessary and one more if we are working in any react project which is in mature state there we cannot change the tech-stack so at-least we can improve it by doing few things like this.

Collapse
lexlohr profile image
Alex Lohr

On one hand, you're reducing the usage of state, on the other you're making it harder for other maintainers, if there are any. Especially if there are side effects that should influence the state (e.g. a server-side confirmation about the toggle), you'll switch back to state anyways.

You still have a point: don't overuse state - and make your state as dumb as possible. It'll save trouble in the long run.

Collapse
aliakakis profile image
Antonios Liakakis

Completely removed useState, useRef in favor of Valtio. Better readability for when internal state goes overboard. No setFn anymore making code difficult to read. Obviously its a personal preference and only for React based projects for which I am pulling the strings(pun intended). Otherwise its Svelte all the way. I am even trying to use it on my day job.

Collapse
shubhamtiwari909 profile image
ShubhamTiwari909

Hey I want to ask something if you don't mind

Collapse
sakethkowtha profile image
sakethk Author
Collapse
shubhamtiwari909 profile image
ShubhamTiwari909

The question is
I have a list in my 'Home Page' and there is another 'Add User' page
So when I add a user on my 'Add User' page using a button, Then how can I show the list of users on my 'Home Page' using map function.

It's like using a button a add something on one page and then show that thing on another page.

I want the logic and some help

Thread Thread
shubhamtiwari909 profile image
ShubhamTiwari909

For example if add a name using input field and that things is added to list but I want to show that list on a different page not on the one I used to add it

Thread Thread
sakethkowtha profile image
sakethk Author

You can try two things

  1. React context or
  2. React Redux

i would say react context will be the better option
refer this for context kentcdodds.com/blog/how-to-use-rea...

Thread Thread
sakethkowtha profile image
sakethk Author

this is basic example : daveceddia.com/usecontext-hook/

Thread Thread
shubhamtiwari909 profile image
ShubhamTiwari909

Thank you I get the concept
I will try to implement it for my project hope it may work

Collapse
anubra266 profile image
Abraham Anuoluwapo

If I got this right. I should use state only for data manipulation. But refs for DOM manipulation

Collapse
sakethkowtha profile image
sakethk Author

If you are doing only dom manipulation then instead of state ref will be good choice.

Collapse
svbofficial1 profile image
SVB_official

Why can't you use the single object in useState? In this case you will avoid 'the horrible performance bottleneck' because you will have only 1 re-render in this way.

Collapse
sakethkowtha profile image
sakethk Author • Edited

Re-rendering will happen once we update the state. Even if we use single state object or multiple state variables it will be same. I guess it wont help 🤔