is there a way to pass a function to the "updater" function that was provide by the `useState()`’s React Hooks?

I am exploring React Hooks and I come up with this code so far and is working. right now is just getting a random gif from the giphy API and rendering on the screen when you clink the button.

import React, {useState} from 'react'
import './App.css';
import axios from 'axios'
const url = process.env.REACT_APP_URL_RANDOM
const apiKey = process.env.REACT_APP_APIKEY

export default function App(){
  const [image, setImage] = useState('')

  const handleRandom = ()=> {
    axios(`${url}?api_key=${apiKey}`).then(response => {
      const img = <img src={response.data.data.image_original_url}
                       alt={response.data.data.title} />
      setImage(img)
    })
  }

  return (
    <div className="App">
      <button onClick={handleRandom}>Get Random Giphy!</button>
      {image}
    </div>
  );
}

I am happy with the result however something tells me that declaring a function outside the function component would be more beneficial. for example, I might add other buttons hitting differents endpoints, and having to declare this function inside the component I think is not a good practice in terms of performance, TLDR: I don't want to declare these functions every time the component gets rendered.

so I came up with this second idea.

import React, {useState} from 'react'
import './App.css';
import axios from 'axios'
const url = process.env.REACT_APP_URL_RANDOM
const apiKey = process.env.REACT_APP_APIKEY

const handleRandom = ()=> {
  console.log("calling handleRandom")
  axios(`${url}?api_key=${apiKey}`).then(response => {
    const img = <img src={response.data.data.image_original_url}
                     alt={response.data.data.title} />
    console.log("returning IMG")
    return img
  })
}

export default function App() {
  console.log("render")
  const [image, setImage] = useState('')
  return (
    <div className="App">
      <button onClick={()=> setImage(handleRandom)}>Get Random Giphy!</button>
      {image}
    </div>
  );
}

so here I would be calling the setImage "updater" on the click event, and the argument is whatever the function handleRandom returns.

and the problem that I am facing is this.

when I console log to see the order of the exections

Even that I am using .then() to resolve to promise it looks like is not waiting for the response and calling the render method right away, and then when the response gets back we can see the data, and since the render method was executed already the page does not update with the new image.

Maybe I am missing something here or this should be a good example to try using the "useReducer" hook?



Read more here: https://stackoverflow.com/questions/64947787/is-there-a-way-to-pass-a-function-to-the-updater-function-that-was-provide-by

Content Attribution

This content was originally published by thiago89 at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: