1

I would like to be able to conditionally set a state based on previous state changes with React Hooks. But if the state remains the same the component shouldn't re-render.

When using class components, I was able to achieve this using:

this.setState(prevState => {
   if(prevState.value !== true) {
     return { value: true }
   }

   return null
})

The code above sets the state to true, only if it's not true. However, if it's already true, the component doesn't re-render. I would like to achieve the same effect with React Hooks.

I know that with React Hooks, I can use the prevState like this:

setValue(prevValue => {
   // some code
   return newValue
})

However, I don't know how to prevent re-render if the state remains the same. Is it possible for me to prevent render after using React Hooks prevState? Thank you for your concern.

batatop
  • 979
  • 2
  • 14
  • 31
  • `if (!state.value) setState({ value: true });`? – Andy Aug 15 '21 at 10:34
  • @Andy Thank you for your suggestion. I am currently using this. However, as far as I know, it's not the best practice because it can lead to incorrect results. Here is a link about that: https://stackoverflow.com/a/54807520/8318855. Please let me know if I'm mistaken. – batatop Aug 15 '21 at 10:40
  • If your state is only one object with one property of `value` you can use it. If not `if (!state.value) setState({ ...state, value: true });` may be better so you preserve all the other properties in state. – Andy Aug 15 '21 at 10:59

2 Answers2

0

Two ways:

  1. Use of pure components using life cycle hooks or useMemo in React Hooks.
  2. shouldComponentUpdate() use the change of state login inside this hook.
0

Wrap your component by memo

import { useEffect, useState, memo } from "react";

const App = () => {
  const [test, setTest] = useState(false);

  useEffect(() => {
    console.log("re-rendered");
  });

  const setTestToTrue = () => {
    setTest((v) => {
      if (v !== true) return true;
      return v;
    });
  };

  return (
    <div className="App">
      <button onClick={setTestToTrue}>Set test to true</button>
    </div>
  );
};

export default memo(App);