I Cannot Get React's "useMemo" Array of Dependencies to Work

3.1k views Asked by At

I am trying to understand how the dependencies in React Hooks work. It sounded simple enough but in the following artificial example, I cannot get the Memo to print when the variables are updated by clicking on the "Done" text.

I believe if those were React's setState variables, they will work. I have seen examples where simple variables were given in the array of dependencies.

The actual use case is in conjunction with useTable. In most cases, it will run into a recursive loop (e.g. using fooArr as the dependency). So I'm trying to distill it down and see what am I missing.

Thanks Matt

import { useMemo } from "react";

export default function Page(props) {
    const fooArr = [1]
    const num = 2

    function update(){
        ++num
        fooArr.push(2)
        console.log("Update")
        console.log(num)
        console.log(fooArr.length)
    }

    useMemo(() =>  { console.log("Memo"); return {}}, [fooArr, fooArr.length, num])

    return <div onClick={update}>done</div>;
}
1

There are 1 answers

1
CertainPerformance On

There are a couple issues here.

  • Components only re-render when a state setter is called. If you never call a state setter anywhere in your application, React will never re-render.
  • Even if you did call a state setter sometime, your fooArr and num variables are declared each time the component runs, and are completely independent from each other across renders - they aren't stateful, so putting them into the dependency array wouldn't make sense. Make them stateful instead, and call their state setters instead of reassigning or mutating them.

function Page(props) {
    const [fooArr, setFooArr] = React.useState([1]);
    const [num, setNum] = React.useState(1);
    function update(){
        setNum(num + 1);
        setFooArr([...fooArr, 2]);
        console.log("Update")
    }

    React.useMemo(() =>  { console.log("Memo"); return {}}, [fooArr, fooArr.length, num])

    return <div onClick={update}>done</div>;
}

ReactDOM.render(<Page />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>