Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

216
Vistas
How to fetch onChange from select value only when select ? is it possible without using useEfect?

So I was trying to fetch some anime data based on the options I have in select (genre), the problem is that the fetch doesn't happen onChange in my select only after changing option twice, I have tried to use useEffect but the problem with that it's fetching immediately without changing the select value.

can someone help and explain what I'm doing wrong?

here is my code on codesandbox

index.js

function App() {
  const [list,setList]=useState([])
  const [genre,setGenre]=useState(0)


  const fetchData=()=>{
    const options = {
      method: 'GET',
      url: `https://jikan1.p.rapidapi.com/genre/anime/${genre}/1`,
      headers: {
        'x-rapidapi-host': 'jikan1.p.rapidapi.com',
        'x-rapidapi-key': '*******************************'
      }
    };
    
    axios.request(options).then(function (response) {
      console.log(response.data.anime);
      setList(response.data.anime)
    }).catch(function (error) {
      console.error(error);
    });
  }

    

  const handleChange=(e)=>{
    setGenre(e.target.value)
    fetchData()
    
  }
  
  return (
    <div className="mx-auto px-8 py-4 flex flex-col justify-center">

      <div>
      <h1>Design with Tailwind</h1>
      
      <select name="genre" className='p-2 bg-bg-prime'  id="genre"  onChange={handleChange}>
            <option value="1" >Action</option>
            <option value="2" >Adventure</option>
            <option value="4" >Comedy</option>
      </select>
      </div>
        <div>
          {list && (
            list.map((an)=>(
              <p key={an.title}>{an.title}</p>
            ))
          )}
        </div>
    </div>
  )
}

const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

While you are calling fetchData after the setGenre, according to react docs :

State Updates May Be Asynchronous

So basically fetchData is called before the state value is actually updated (and this is causing your request to be performed with the old value instead of the requested one). A fix would be something like:

...
useEffect(() => {
  fetchData();
}, [genre]) 

const handleChange=(e)=>{
  setGenre(e.target.value)
}

If you really want to keep your approach you could also do something like:

const handleChange=(e)=>{
  setGenre(e.target.value)
  fetchData(e.target.value)
}

and use the variable in fetch data (so

const fetchData = (selectedGenre) => {
  ...
    url: `https://jikan1.p.rapidapi.com/genre/anime/${selectedGenre}/1`,
  ...

I recommend first approach, but both should work.

Also if you use a valid value as the initial value for the genre along with the first approach you can get the list populated by default (for your example const [genre,setGenre]=useState(1) )

about 4 years ago · Juan Pablo Isaza Denunciar

0

I couldn't see anything in your codesandbox.

I think the right approach would be to use the useEffect as you were trying, this way you make sure the 'genre' value you're using in your 'fetchData' function is the right one.

Now, the only thing that you were missing was an state to prevent the 'fetchData' function from running right after the component is rendered and make it run only after you've changed the 'genre' state for the first time.

function App() {
  const [list,setList]=useState([])
  const [genre,setGenre]=useState(0)
  const [selectCount, setSelectCount]=useState(0)

  const fetchData=async()=>{
    const options = {
      method: 'GET',
      url: `https://jikan1.p.rapidapi.com/genre/anime/${genre}/1`,
      headers: {
        'x-rapidapi-host': 'jikan1.p.rapidapi.com',
        'x-rapidapi-key': '*******************************'
      }
    };
    
    axios.request(options).then(function (response) {
      console.log(response.data.anime);
      setList(response.data.anime)
    }).catch(function (error) {
      console.error(error);
    });
  }

  const handleChange=(e)=>{
    setSelectCount(selectCount + 1)
    setGenre(e.target.value)
  }

  useEffect(() => {
    if (selectCount === 0) return
    fetchData()
  }, [genre])
  
  return ...Your JSX goes here...
}

const rootElement = document.getElementById('root')
ReactDOM.render(<App />, rootElement)
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda