Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update React Hooks State During Render Using useMemo

Can useMemo be used just to avoid extra referential equality checking code/vars when setting state during a render?

Example: useMemo with a setState during render taken from this rare documented use case:

function ScrollView({row}) {
  let [isScrolling, setIsScrolling] = useState(false);

  const lessCodeThanCheckingPrevRow = useMemo(
    () => {
      // Row changed since last render. Update isScrolling.
      setIsScrolling(true); // let's assume the simplest case where prevState isn't needed here
    },
    [row]
  );

  return `Scrolling down: ${isScrolling}`;
}

Above drastically reduces code and extra vars, only otherwise used for equality checks, so why do the docs imply referential equality checks should be done manually?

like image 343
ecoe Avatar asked Sep 25 '19 15:09

ecoe


1 Answers

This seems to be an elegant way to reduce boiler plate to me. I created a codesandbox to validate its behaviour.

const UnitUnderTest = ({prop}) => {
  let [someState, setSomeState] = useState(false);

  const lessCodeThanCheckingPrevRow = useMemo(
    () => setSomeState(current => !current), 
    [prop],
  );

  useEffect(() => console.log('update finished'), [prop])

  console.log('run component');

  return `State: ${someState}`;
}

const App = () => {
  const [prop, setProp] = useState(false);
  const handleClick = () => setProp(current => !current);

  return (
    <div>
      <button onClick={handleClick} >change prop</button>
      <UnitUnderTest prop={prop} />
    </div>
  )
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit recursing-hopper-4ynjm

Output when clicking the button to change the prop passed to the component:

> run component 
> run component 
> update finished 

As you can see the component has been run twice before the update cycle completed. This is equivalent to the the behaviour of getDerivedStateFromProps.

I guess that there is no deeper thought behind why the docs propose a slightly different technique. In a way this is a manual check too but in a neat way. +1 for the idea.

like image 122
trixn Avatar answered Oct 02 '22 20:10

trixn