Home > Mobile >  How to execute a function AFTER an API-Call was made with setState within useEffect?
How to execute a function AFTER an API-Call was made with setState within useEffect?

Time:05-08

i am a React newbie (30h learning) and some basic Javascript background. Now i am learning with a course, and tried to "leave" the path. But i am curious how my intended goal could be achieved.

There is a Memegenerator who get all the images of memes from an API in the beginning of the rendering. This is solved with an useEffect-Hook. Now i want that the function getMemeImage() is running ONCE at the beginning AFTER the API-Call was made and the state was updated (this is not part of the course, but i want to try it anyway).

But its giving me an error: "Can't perform a React state update on an unmounted component"

While my research i found that things like didMount(tbh i not understand) and so on are not the "modern" way of react with primarily using hooks and you can simply use an second useEffect. But that is unfortunately not working for me.

How can i solve this and is there an "simple" way for a beginner or it is advanced stuff? I thought maybe to use a timeoutfunction, but seems to be very bad coding.

import React from "react"

export default function Meme() {
    const [meme, setMeme] = React.useState({
        topText: "",
        bottomText: "",
        randomImage: "" 
    })
    const [allMemes, setAllMemes] = React.useState([])

React.useEffect(() => {   /* first useEffect */
    fetch("https://api.imgflip.com/get_memes")
        .then(res => res.json())
        .then(data => setAllMemes(data.data.memes))
}, [])




React.useEffect(() => {   /* This should run after the setAllMemes in the first useEffect was complete */

    getMemeImage()
}, [allMemes])



function getMemeImage() {
    const randomNumber = Math.floor(Math.random() * allMemes.length)
    const url = allMemes[randomNumber].url
    setMeme(prevMeme => ({
        ...prevMeme,
        randomImage: url
    }))
    
}

function handleChange(event) {
    const {name, value} = event.target
    setMeme(prevMeme => ({
        ...prevMeme,
        [name]: value
    }))
}

return (
    <main>
        <div className="form">
            <input 
                type="text"
                placeholder="Top text"
                className="form--input"
                name="topText"
                value={meme.topText}
                onChange={handleChange}
            />
            <input 
                type="text"
                placeholder="Bottom text"
                className="form--input"
                name="bottomText"
                value={meme.bottomText}
                onChange={handleChange}
            />
            <button 
                className="form--button"
                onClick={getMemeImage}
            >
                Get a new meme image            
  • Related