isotropic-2022
Share
Blog
Search
Menu

How To Fix The "useEffect must not return anything besides a function" Warning

By James LePage
|
Last updated on August 22nd, 2022
|

Continuing our series about React, specifically React hooks, let’s take a look at the useEffect hook. This is a very powerful hook that allows you to handle side effects of state or prop changes as well as creating on-mount functionality similar to componentDidMount in class components.

image-44-8

As such, this hook is frequently used for asynchronous requests like loading data for a component as soon as that component is rendered or loading new data based off another value changing. Despite its many uses, creating this sort of functionality can be tricky and you may end up running into a warning like useEffect must not return anything besides a function, which is used for clean-up.

The Problem

As mentioned previously, wanting to do something asynchronously inside of useEffect is a common use-case for this hook. For example, imagine you have a component that shows a list of users but those users come from a database so you must request them on page load. In its simplest form, you might have a component like this:

const UsersComponent = () => {
  const [users, setUsers] = useState([]);
  const [usersLoading, setUsersLoading] = useState(false);

  useEffect(async () => {
    setUsersLoading(true);
    // getUsers is your api call function that returns a promise
    const result = await getUsers();
    setUsers(result);
    setUsersLoading(false);
    // no values in the dependency array means this effect will run once when the component mounts
  }, []);

  return (
    <div>
      <h1>Users</h1>
      <div>
        {users.map((user) => (
          <div key={user.id}>{user.username}</div>
        ))}
      </div>
    </div>
  );
};Code language: JavaScript (javascript)

Here you can see the basic setup for the component described above. When the page loads, the component should load the users from an API and once that is finished it will update its state accordingly. Looks great, but this will trigger the useEffect must not return anything besides a function, which is used for clean-up warning mentioned above. That is because the callback itself is returning a promise which is incompatible with useEffect.

The Solution

The fix here is actually quite simple. You should wrap your asynchronous work in a function and then just call that from the useEffect callback. Here is that solution using the example above:

const UsersComponent = () => {
  const [users, setUsers] = useState([]);
  const [usersLoading, setUsersLoading] = useState(false);

  useEffect(() => {
    // wrap your async call here
    const loadData = async () => {
      setUsersLoading(true);
      const result = await getUsers();
      setUsers(result);
      setUsersLoading(false);
    };

    // then call it here
    loadData();
  }, []);

  return (
    <div>
      <h1>Users</h1>
      {usersLoading && <div>Loading...</div>}
      <div>
        {users.map((user) => (
          <div key={user.id}>{user.username}</div>
        ))}
      </div>
    </div>
  );
};Code language: JavaScript (javascript)

Keep in mind that even though this works you should probably refactor your solution further to handle race-conditions and cleanup of your asynchronous calls but that is outside of the scope of this article.

Conclusion

React hooks, asynchronous calls, and side effects are all complicated topics so combining them can be tricky to say the least. Hopefully this solution helps with your use case and, as always, feel free to leave any feedback you may have. Thanks for reading!

The Isotropic Codex is a collection of code snippets and education for WordPress, web and WooCommerce developers.
Subscribe & Share
If you liked this content, subscribe for our monthly roundup of WordPress news, website inspiration, exclusive deals and interesting articles.
Unsubscribe at any time. We do not spam and will never sell or share your email.
Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
david
david
2 years ago

Many Thanx!!!! This helped me tremendously

Article By
James LePage
Contributors/Editors
notloggedin
James LePage is the founder of Isotropic, a WordPress education company and digital agency. He is also the founder of CodeWP.ai, a venture backed startup bringing AI to WordPress creators.
We're looking for new authors. Explore Isotropic Jobs.
linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram