<p dir="auto">So I'm using a custom <code class="notranslate">usePrevious</code> hook that returns the 'previous value' which is as far as I know pretty common practice. It leverages a ref inside the hook. When I declare a ref inside a functional component and use this in a <code class="notranslate">useEffect</code>, <code class="notranslate">react-hooks/exhaustive-deps</code> does not require me to add the ref to the dependencies list of a <code class="notranslate">useEffect</code>, but using <code class="notranslate">usePrevious</code> does.</p>
<p dir="auto">React version: <code class="notranslate">"react": "^17.0.1",</code></p>
<h2 dir="auto">Steps To Reproduce</h2>
<p dir="auto">Link to code example: <a href="https://codepen.io/spassvogel/pen/JjbXKJL?editors=1111" rel="nofollow">https://codepen.io/spassvogel/pen/JjbXKJL?editors=1111</a></p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="const usePrevious = (value) =&gt; {
    const ref = React.useRef();
    React.useEffect(() =&gt; {
      ref.current = value;
    }, [value]);
    return ref.current;
};

const TestComponent = () =&gt; {
  const [state, setState] = React.useState(0);
  const previousState = usePrevious(state)
  
  React.useEffect(() =&gt; {
     console.log('current state', state)
     console.log('previous state', previousState)

  }, [state]); // ESLINT COMPLAINS 
  return null;
};"><pre class="notranslate"><code class="notranslate">const usePrevious = (value) =&gt; {
    const ref = React.useRef();
    React.useEffect(() =&gt; {
      ref.current = value;
    }, [value]);
    return ref.current;
};

const TestComponent = () =&gt; {
  const [state, setState] = React.useState(0);
  const previousState = usePrevious(state)
  
  React.useEffect(() =&gt; {
     console.log('current state', state)
     console.log('previous state', previousState)

  }, [state]); // ESLINT COMPLAINS 
  return null;
};
</code></pre></div>
<h2 dir="auto">The current behavior</h2>
<p dir="auto"><code class="notranslate">react-hooks/exhaustive-deps</code> complains about the dependency list of <code class="notranslate">useEffect</code> is missing <code class="notranslate">previousState</code>.</p>
<h2 dir="auto">The expected behavior</h2>
<p dir="auto"><code class="notranslate">react-hooks/exhaustive-deps</code> realizes that <code class="notranslate">usePrevious</code> is leveraging <code class="notranslate">useRef</code> and thus doesn't need its return value in the dependency list.</p>
<p dir="auto">A workaround would be to duplicate the code of <code class="notranslate">usePrevious</code> in every component, then <code class="notranslate">react-hooks/exhaustive-deps</code> does not complain. but yeah...</p>
<p dir="auto">Describe what you were doing when the bug occurred:<br>
1.<br>
2.<br>
3.</p>
<hr>
<h2 dir="auto">Please do not remove the text below this line</h2>
<p dir="auto">DevTools version: 4.2.1-3816ae7c3</p>
<p dir="auto">Call stack: at chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:40:157108<br>
at Map.forEach ()<br>
at commitIndex (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:40:157054)<br>
at e.getRankedChartData (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:40:157577)<br>
at vl (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:40:314907)<br>
at gi (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:32:59907)<br>
at jl (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:32:107381)<br>
at Lc (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:32:92715)<br>
at Pc (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:32:92640)<br>
at wc (chrome-extension://fmkadmapgofadopljbjfkapdkoienihi/build/main.js:32:89544)</p>
<p dir="auto">Component stack: in vl<br>
in div<br>
in div<br>
in div<br>
in wo<br>
in Unknown<br>
in n<br>
in Unknown<br>
in div<br>
in div<br>
in Li<br>
in $e<br>
in dn<br>
in Ca<br>
in Pc</p>