Do React hooks need to return a value?

Viewed 11781

I've recently started to build out custom hooks in my React application and have been following the documentation on the React website. However, the hooks which I am building require no return value as they set up data for Redux on initialization.

Example:

// custom hook
export const useSetup() {
  useEffect(() => {
    if (data) fetch().then(data => dispatch(setInit(data)))
  }, [dispatch])
}


// functional component
export function Details() {
  useSetup()

I can't find documentation explicitly stating that a hook needs to return anything. However, I cannot find an example of a hook not returning something. Can someone advise on if this approach is correct?

1 Answers

Yes, your approach is correct. React hooks are not required to return anything. The React documentation states that:

We don’t have to return a named function from the effect. We called it cleanup here to clarify its purpose, but you could return an arrow function or call it something different.

The return value of a function that is passed as an argument to a hook has a special use in the lifecycle of the React component it belongs to. Essentially, that return value is expected to be a function and executes before the component with the hook re-renders or is unmounted. React documentation call this kind of hook an "effect with cleanup."

The React documentation uses the example below to show what a useEffect hook looks like:

const [count, setCount] = useState(0);

// Similar to componentDidMount and componentDidUpdate:
useEffect(() => {
  // Update the document title using the browser API
  document.title = `You clicked ${count} times`;
});

As you can see, the anonymous function that is used as an argument to useEffect does not have a return statement.

You can verify this by changing the function a little bit to log the return value:

const count = 0;

const a = () => {
  // Update the document title using the browser API
  document.title = `You clicked ${count} times`;
}

console.log(a());

This prints undefined.

You can also use console.log on the useEffect function to see that it also returns undefined.

If you changed the hook to this:

useEffect(() => {
  // Update the document title using the browser API
  document.title = `You clicked ${count} times`;
  return () => {
    console.log('cleanup');
  }
});

You would see the "cleanup" message every time the component re-renders or is unmounted. You would have to trigger the re-render by updating the state of the component in some way.

Related