How to force an update to Components in React
Tags: javascript, react, tutorial, productivity
Published: 2023-08-13 02:28:30

Have you ever come across a situation in which you submit the changes to your backend and the change is not visible in your react application? If yes, then, like me, you are using the _**useEffect**_ hook to retrieve the data either from the backend/localStorage.

For this exact situation, there is another hook available in react called _**useReducer()**_. If you go to the official documentation of React, the definition of the useReducer hook is given as follows:

_" **useReducer** is a React Hook that lets you add a reducer to your component. "_

With it's syntax as:

`const [state, dispatch] = useReducer(reducer, initialArg, init?)`

As this definition isn't very straightforward, it is not very helpful if you are a beginner. The purpose of this article is to deconstruct this definition into simpler terms.

As it is easier to understand with an example, here is a simple react code which adds some data into the localStorage everytime the button is clicked.

Code:

```
import { useState, useEffect } from 'react';
import './App.css';

function App() {
  const [count, setCount] = useState(0);
  const [dataValues, setdataValues] = useState('');
  const [Loaded, setLoaded] = useState(false);
  useEffect(() => {
    let val;
    val = JSON.parse(localStorage.getItem('DataValues') || '[]');
    setdataValues(val);
    setLoaded(true);
  }, []);
  const handleClick = () => {
    const data = { source: 'meteor' };
    dataValues.push(data);
    localStorage.setItem('DataValues', JSON.stringify(dataValues));
  };

  return (
    <>
      {Loaded ? (
          <h1>React</h1>
          <div className="card">
            <button onClick={() => handleClick()}>Click me</button>
          </div>
          {dataValues.map((data, index) => (
            <div>
              <span key={index} style={{ textAlign: 'center', color: '#fff' }}>
                {data.source}
              </span>
              <br />
            </div>
          ))}
        </div>
      ) : (
        ''
      )}
    </>
  );
}

export default App;

```

If we run the development build of this application, we can observe this:

{% youtube BiGO2LzcO9A %}

From the above video, it can be clearly observed that the changes are made visible _**only when the website is reloaded**_. This is unacceptable for single page applications. Hence, we need to find a way to force an update to the react application once we made changes to the localStorage/backend. 

For this exact purpose, we use the _**useReducer**_ react hook. The syntax for the useReducer hook is given below:

`const [state, dispatch] = useReducer(reducer, initialArg, init?)`

_**reducer**_ => a function that defines how the state is updated
_**initialArg**_ => sets the initial value of the state
_**init?**_ => optional argument that specifies the initializer function that should return the initial state

The useReducer hook once initialized sets the value of state to init(initialArg)(if init is specified) or initialArg.

The changes we should make to our code to force an update is given below:

```
  const [dataValues, setdataValues] = useState('');
  const [Loaded, setLoaded] = useState(false);

  const [ignore, forceUpdate] = useReducer((x) => x + 1, 0);
  useEffect(() => {
    let val;
    val = JSON.parse(localStorage.getItem('DataValues') || '[]');
    setdataValues(val);
    setLoaded(true);
  }, [ignore]);
  const handleClick = () => {
    const data = { source: 'meteor' };
    dataValues.push(data);
    localStorage.setItem('DataValues', JSON.stringify(dataValues));
    forceUpdate();
  };

```

What this does is that, whenever we call **handleClick**, after performing necessary actions the **handleClick** calls the **forceUpdate** function. The **forceUpdate** updates the value of the state from its initial state. Then, we are setting dependency of the useEffect hook to the state(ignore). Hence, whenever we click the button, **ignore** gets updated and then due to that the component is refreshed and we can instantly see the changes in the react application.

The output now looks like:

{% youtube cvx8CY0bKhU %}

Feel free to leave a like if this article was helpful to you.