# useState vs useRef: Tussle of Titans

# What are Hooks? 🙄

Hooks let developers use state and other React features without writing a class. Hooks were introduced in React 16.8 to facilitate programmers in the reusability of React code. 

They are the functions that "hook into" React state and lifecycle features from function components. It does not work inside classes.

# **When would I use a Hook?**

If writing a function component and realizing the need to add some state to it, previously we had to convert it to a class. Now we can use a Hook inside the existing function component.

## Rules of Hooks:

- Hooks should only be called from the top level of your React function
- Hooks must not be called from nested code (e.g., loops, conditions).
- Hooks may also be called at the top level from custom Hooks.

## **Now let’s look at the two hooks which are most confused between** 😬

# useState Hook: 😍

## Definition:

useState hook is the primary building block that enables functional components to hold state between re-renders. It enables the development of the component state for functional components.

## Usage: 🙃

```jsx
import React, { useState } from "react";

export default function App() {
  const [count, setCount] = useState(0);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <button onClick={() => setCount(count + 1)}>Count is :{count}</button>
    </div>
  );
}
```

Above is the code for functional implementation of React `useState` and below is the equivalent CodeSandbox Output .

[https://codesandbox.io/embed/priceless-fast-hijeoo?fontsize=14&hidenavigation=1&theme=dark](https://codesandbox.io/embed/priceless-fast-hijeoo?fontsize=14&hidenavigation=1&theme=dark)

Let’s see the same code using class components-based method.

```jsx
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    };
  }

  render() {
    return (
      <div>
        <p>You clicked {this.state.count} times</p>
        <button onClick={() => this.setState({ count: this.state.count + 1 })}>
          Click me
        </button>
      </div>
    );
  }
}
```

We see how much the code is reduced significantly and using functional components and hook also makes code much clearer by not using this keyword and eliminating a wrapper constructor within `class` component.

## What does useState do? 🤔

First of all, it declares ‘state variables’. It is used to preserve value between the function calls. Normally, common Javascript variables like ( `let`, `var`, `const`) disappear after the function call. However, state variables preserve the values.

## Explaining the Syntax:

```jsx
[count,setCount]=useState(0)
```

- `count` is the state variable that will be used to represent the value assigned using the hook.
- `setCount` is a functional variable whose sole purpose is updating `count` state variable.
- Within brackets, after `useState` initial argument is passed which is used for the initial value of the count after initial rendering.
- Square Brackets mean that when we declare a state variable with `useState` it returns an array with two items. The first one is the current value and the second is a function that updates it.

> React will remember its current value between re-renders, and provide the most recent one to our function. If we want to update the current `count`, we can call `setCount`
When the App component re-renders, its children would re-render.
> 

## Gotcha! 😳

<aside>
🔥 When a state variable is initialized using some prop value as default (snippet below), the prop value is used *only*
 the first time when the state is created. Any further updates to the prop won’t automatically ‘*sync*’ the local state of the component.

</aside>

```jsx
const [localState, setLocalState] = useState(props.theme);
```

# useRef Hook: 😍

## Definition:

The useRef Hook **allows persisting values between renders**. It can be used to store a mutable value that does not cause a re-render when updated. It can be used to access a DOM element directly.

It does everything that useState does but without re-rendering the components.

`useRef`returns a mutable ref object whose `.current`property is initialized to the passed argument (`initialValue`). The returned object will persist for the full lifetime of the component.

## The major question that arises is why use useRef if we have useState? 🤔

- Easier to work with as updates are synchronous.
- Do not trigger re-render. Performance optimization.
- Prevents render thrashing
- Can be used if we want the state to presist value throughout the component lifecycle.
- If we want to access the DOM element directly `useRef` should be used.

## Usage: 😜

```jsx
import { useState, useRef } from "react";
import "./styles.css";
export default function AppDemo11() {
  const [value, setValue] = useState("");
  const valueRef = useRef();
  console.log("render");
  const handleClick = () => {
    console.log(valueRef);
    setValue(valueRef.current.value);
  };
  return (
    <div className="App">
      <h4>Value: {value}</h4>
      <input ref={valueRef} />
      <button onClick={handleClick}>click</button>
    </div>
  );
}
```

We see the code used for `useRef` and equivalent output in CodeSandbox.

[https://codesandbox.io/embed/cranky-ellis-1s6jrt?fontsize=14&hidenavigation=1&theme=dark](https://codesandbox.io/embed/cranky-ellis-1s6jrt?fontsize=14&hidenavigation=1&theme=dark)

We see that component only renders after button click function rather than rendering on each keystroke.

When we “submit” the input with a button to update the state variable `value`.With the `ref`property, React provides direct access to React components or HTML elements.

```jsx
<input ref={valueRef} />
```

---

If this had been done using `useState` and `onChange` which each keystroke input the component would have re-rendered. With each keystroke, component is re-rendered. 

We see that in effect in the below code and it’s output in CodeSandBox.

```jsx
import { useState, useRef, useEffect } from "react";
import "./styles.css";
export default function AppDemo11() {
  const [value, setValue] = useState("");
  const rendercount = useRef(0);

  useEffect(() => {
    rendercount.current = rendercount.current + 1;
    console.log(rendercount.current);
  });
  const handleChange = (e) => {
    setValue(e.target.value);
  };
  return (
    <div className="App">
      <input value={value} onChange={handleChange} />
      <h4>Renders:{rendercount.current} </h4>
    </div>
  );
}
```


%[https://codesandbox.io/embed/competent-cerf-6e3vp0?fontsize=14&hidenavigation=1&theme=dark]
(https://codesandbox.io/embed/competent-cerf-6e3vp0?fontsize=14&hidenavigation=1&theme=dark)



However, using `useRef` makes sure that the component is rendered only once after the button is clicked.

## Explaining the Syntax:

```jsx
const valueRef = useRef(null);
const onButtonClick = () => {
   
   console.log(valueRef.current.value);
  };
```

- `valueRef` is the variable that stores the value to be persisted.
- Within the brackets, after the `useRef` statement, it is provided the initial value which should be assigned to useRef on the first render.
- We see that within the Button click function we access value within `valueRef` using .`current` keyword. This is because `useRef` is like a box that holds its mutable value in its `.current` property.

> Keep in mind that `useRef`*doesn’t*notify when its content changes. Mutating the `.current`property doesn’t cause a re-render.
> 

## Gotcha! 😳

<aside>
🔥 `useState` is a React State i.e changes using it come under controlled state change. However, `useRef` is called a non-react state, and state change using it is called uncontrolled state change. It should be noted that React recommends using a controlled state method however in general practice it’s good to use `useRef`

</aside>

# Examples of different use cases for useState vs useRef: 🤠

We have already seen two major use cases for useRef over useState

1. Accessing DOM input using ref directly.
2. Persisting values of mutable variables and not causing re-renders on updation.

### Let’s see some more use cases of these points.

- **In the first example, we simply try counting the no of renders using `useRef` and `useState`.**

**useState code:**

```jsx
import { useState, useRef, useEffect } from "react";
import "./styles.css";
export default function AppDemo11() {
  const [value, setValue] = useState("");
  const [rendercount,setrenderCount] = useState(0);

  useEffect(() => {
    setrenderCount(rendercount+ 1);
    
  });
  const handleChange = (e) => {
    setValue(e.target.value);
  };
  return (
    <div className="App">
      <input value={value} onChange={handleChange} />
      <h4>Renders:{renderco} </h4>
    </div>
  );
}
```

This above code will cause infinite renders as every time `rendercount` value is updated the entire component is re-rendered.

**useRef code:**

Equivalent use case can be achieved using `useRef` whererin within `useEffect` hook ( important to use within `useEffect` to avoid side effects) `rendercount.current` value is updated which doesn’t trigger any re rendering. 

```jsx
import { useState, useRef, useEffect } from "react";
import "./styles.css";
export default function AppDemo11() {
  const [value, setValue] = useState("");
  const rendercount = useRef(0);

  useEffect(() => {
    rendercount.current = rendercount.current + 1;
    console.log(rendercount.current);
  });
  const handleChange = (e) => {
    setValue(e.target.value);
  };
  return (
    <div className="App">
      <input value={value} onChange={handleChange} />
      <h4>Renders:{rendercount.current} </h4>
    </div>
  );
}
```

- **In the second example Let’s take a second use case of creating a timer using `useState` and `useRef` .**

The code is for printing “A second has passed” in console for each passing second

**useState code:**

We see in this code that it goes into an infinite loop and keeps on re-rendering.

As with each update of state variable `intervalUse` component is re-rendered. Code goes into infinite loop hell.

```jsx
import "./styles.css";
import React, { useRef, useEffect, useState } from "react";

export default function App() {
 
  const [intervalUse,setintevalUse]= useState()

  useEffect(() => {
    const id = setInterval(() => {
      console.log("A second has passed");
    }, 1000);
    
   
    setintevalUse(id)
    
  });
  
  return (
    <div>
      
    </div>
  );
}
```

**useRef code:** 

So to prevent inifinte loop hell we use `useRef`.

With each passing second “A second has passed” is printed on the console and state variable `val` is updated which is rendered on the screen.

```jsx
import "./styles.css";
import React, { useRef, useEffect, useState } from "react";

export default function App() {
  const[val,setVal]=useState(0)
  const intervalRef = useRef();

  useEffect(() => {
    const id = setInterval(() => {
      setVal(val+1)
      console.log("A second has passed");
    }, 1000);
    
   
    intervalRef.current = id;
    
    return () => clearInterval(intervalRef.current);
  });

  const handleCancel = () => clearInterval(intervalRef.current);
  
  return (
    <div>
     <div>Value is {val}</div>
    </div>
  );
}
```

See the ouput in CodeSandBox. Using `useRef` makes sure that there is no case for inifinite rendering.

[https://codesandbox.io/embed/upbeat-ganguly-nbg47c?fontsize=14&hidenavigation=1&theme=dark](https://codesandbox.io/embed/upbeat-ganguly-nbg47c?fontsize=14&hidenavigation=1&theme=dark)

## Finally all the Differences in Brief: 😌

- Both preserve their data during render cycles and UI updates, but only the `useState` Hook with its updater function causes re-renders.
- `useRef` returns an object with a `current` property holding the actual value. In contrast, `useState` returns an array with two elements: the first item constitutes the state, and the second item represents the state updater function
- `current` property in useRef is mutable however `useState` state variable is not. We need updater function to update useState state variable.
- `useState` and `useRef` both are Hooks, but only `useRef` can be used to gain direct access to React components or DOM elements.

# Concluding: 🤩

It should be clear by now that `useState` is to be used if we want to update data and cause a UI update.

And `useRef` is to be used if data is to be persisted throughout the lifecycle without re-renders.

## This is all meet you soon 🤗
