0

I am trying to call this endpoint to generate random memes when a a user clicks on a button. I am using the fetch api inside the useEffect hook,and the button works fine, but when I click it, there is splash of a new image for a split second and then the image disappears as the app gets re-rendered. I do not know why this is happening.

Here is my code:

import {useState, useEffect, useCallback} from 'react';

const Ui = () => {

// updating the state

const [url, setUrl ] = useState({})
const [meme, setMeme ] = useState([])




useEffect(()=>{
   fetch('https://api.imgflip.com/get_memes')
    .then(res => res.json())
    .then(data=> setMeme(data.data.memes))

}, [])



// function that brings a random image

const getAMeme = ()=>{
    const randomNum = Math.floor(Math.random() * meme.length)
    const url = meme[randomNum].url
    console.log(url)
    setUrl(prevUrl =>({
        ...prevUrl, 
        randomImage: url
    }))
   
}



    return (
        <div className = "ui">

                {/* form */}

                <form>

                    <input placeholder="Enter first sentence"></input>
                    <input placeholder="Enter second sentence"></input>
                    <button onClick={getAMeme}>Generate Meme</button>
            
                </form>                

                {/* meme image */}
                <div className="image">
                    <img src={url.randomImage} alt="cool" />
                </div>
            
        </div>
    );
}

export default Ui;

I am calling the endpoint inside the useEffect but it seems like the app gets rerendered multiple times.

Owais
  • 17
  • 5
  • It seems that the form makes your page refresh. try removing it. – Radika Dilanka Mar 12 '23 at 14:17
  • Thank you for your response, but that would defeat the whole purpose of creating this app as I am trying to get input from users and then show the text on the randomly generated image. – Owais Mar 12 '23 at 14:20
  • 1
    @RadikaDilanka Thank you, that does solve the problem. I am wondering if there is a way to use the
    tag without getting the app to rerender like that.
    – Owais Mar 12 '23 at 14:22
  • 1
    Try adding `type="button"` to your ` – Mulan Mar 12 '23 at 14:39
  • Does this answer your question? [Stop form refreshing page on submit](https://stackoverflow.com/questions/19454310/stop-form-refreshing-page-on-submit) – Konrad Mar 12 '23 at 14:46
  • 1. You should listen for `submit` event on form, not `click` on the button. 2. You have to call `preventDefault` on the event object to prevent reloading. To make it clear, it's the default html form behaviour, not related to react in any way – Konrad Mar 12 '23 at 14:47
  • Thanks, @Konrad. preventDefault() method solves the problem. – Owais Mar 12 '23 at 14:52

2 Answers2

2

Having a form will make your page reload. By removing it you can make it work. If you still need to have the form and do the things you can try like this.

    <form onSubmit={(e)=>e.preventDefault()}>
           // ..... form content inside ...
   </form>    
Radika Dilanka
  • 474
  • 4
  • 13
0
<button onClick={getAMeme}>Generate Meme</button>

const getAMeme = (e) => {
    e.preventDefault()
    const randomNum = Math.floor(Math.random() * meme.length)
    const url = meme[randomNum].url
    console.log(url)
    setUrl(prevUrl =>({
        ...prevUrl, 
        randomImage: url
    }))
   
}
Mulan
  • 129,518
  • 31
  • 228
  • 259
Panos
  • 89
  • 1
  • 4