Returning a function in a React hook giving unexpected result

I’m trying to create a React hook that returns a function that users of the hook will invoke. The hook creates a function inside the hook.

Here’s a minimal example

// fetch.js

import { useEffect, useState} from "react";

export const useFetch = () => {
  
  const [fn, setFn] = useState(null);

  useEffect(() => {
    const fn_ = () => console.log("test")
    setFn(fn_)
  }, []);

  return fn;
}
// App.js

import { useFetch } from './fetch';

function App() {
  const fn = useFetch()
  
  return (
    <div className="App">
      hello
    </div>
  );
}

I have the Strict mode disabled as well.

// index.js

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <App />
);

Even though I’m not invoking fn(), I see it getting executed and console log output.

enter image description here

Any idea why this is happening? Pretty sure I’m doing something wrong but can’t figure out what.

Edit:

Thanks for the answer below. Found this explained in React FAQ https://react.dev/reference/react/useState#im-trying-to-set-state-to-a-function-but-it-gets-called-instead

>Solution :

The problem with passing a function to a state setter is it assumes you’re using a functional update.

Like I said in the comments above, the effect hook and state are totally redundant and you should especially not use it for a function

export const useFetch = () => () => console.log("[useFetch] test");

Leave a Reply