React - need call useEffect on click

My app fetches a photo using NASA’s APOD API. The app works properly but I want to add a functionality where it fetches a new photo on click. How do I trigger the useEffect hook(?) on click?

  const [apod, setApod] = useState(null)

  useEffect(() => {
    async function displayApod() {
        const data = getApod()
        data.then(res => {
          if(res) {
            setApod(res[0])
          } else {
            setApod(null)
          }
        })
        .catch(err => console.log(err))
    }
    displayApod()
  }, [])

  const getApod = async() => {
    const response = await fetch(`https://api.nasa.gov/planetary/apod?api_key=${config.apiKey}&count=1`)
    const data = await response.json()
    return data
  }


  if (!apod) {
    return <h1>no image to display</h1>
  } else {
    const { date, explanation, hdurl, title, url } = apod
    return (
  
      <div className='App'>
        <div className="container mx-auto p-4 flex flex-col items-center">
          <p>{title}</p>
          <img src={url}/>
          <p>{date}</p>
          <p>{explanation}</p>
          {/* Need to get new photo onClick */}
          <button onClick={getApod}>New Photo</button>
        </div>

      </div>
    );
  }

hey @yabinivek,

You could put your async function outside of the useEffect and then just call it with an onClick,

  useEffect(() => {
    displayApod()
  }, [])

const getApod = async() => {
    const response = await fetch(`https://api.nasa.gov/planetary/apod?api_key=${config.apiKey}&count=1`)
    const data = await response.json()
    return data
  }

  async function displayApod() {
        const data = getApod()
        data.then(res => {
          if(res) {
            setApod(res[0])
          } else {
            setApod(null)
          }
        })
        .catch(err => console.log(err))
    }

  <button onClick={displayApod}>New Photo</button>

or simpler version…

  const getApod = async() => {
    const response = await fetch(`https://api.nasa.gov/planetary/apod?api_key=${config.apiKey}&count=1`)
    const data = await response.json()
    setApod(data[0])
  }

 useEffect(() => {
    getApod()
  }, [])

<button onClick={getApod}>New Photo</button>

that solution worked, thanks!

1 Like