Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How can I trigger the useEffect() hook with a button?

I have the following code, that loads a random user from an API.
On load, it shows the first name of the fetched user.

Now I want to fetch a new user when clicking the ‘Generate user’ button, but it’s not triggering the useEffect.

I thought I could trigger a refresh by passing the generate var to the dependency array in the useEffect, but it’s not working. Should I make generate part of the state? That seems counter-intuitive for a simple toggle.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Any help / tips appreciated!

import { useEffect, useState } from "react";

const Async = () => {

    let generate = false;
    const [user, setUser] = useState({name: ''});

    useEffect(() => {
        fetch('https://randomuser.me/api/?results=1')
        .then(response => response.json())
        .then(data => setUser({...user, ['name']: data.results[0].name.first}))
        .catch(error => console.error(error));
    }, [generate]);
    
    function newUser()
    {
        generate = !generate;
    }

    return <>
        <button onClick={newUser}>Generate user</button>
        <div>User {user.name}</div>
    </>;

};

>Solution :

You could move generate into a React state that is toggled and triggers a rerender, but it would be better to just abstract the fetch call into a callback that is called by the button element’s onClick handler. Call the function once in a mounting useEffect hook.

import { useEffect, useState } from "react";

const Async = () => {
  const [user, setUser] = useState({ name: '' });

  const generate = () => {
    fetch('https://randomuser.me/api/?results=1')
      .then(response => response.json())
      .then(data => setUser(user => ({
        ...user,
        name: data.results[0].name.first
      })))
      .catch(error => console.error(error));
  };

  // Call once when the component mounts
  useEffect(() => {
    generate();
  }, []);
    
  return (
    <>
      <button onClick={generate}>Generate user</button>
      <div>User {user.name}</div>
    </>
  );
};
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading