Aliénor
Aliénor

Reputation: 93

setState doesn't set immidaltly after a fetch API method

I've read in here a lot of the same question and I apply what works for everybody but it not seems to work for me . I try to fetch data from my API but even with the UseEffect hook my setList don't want to set ListVille. This is my code, do you have an idea why ?

import React, {useEffect, useState} from 'react';
import {Navigate} from 'react-router-dom'
import Entete from './MEP/entete'

function Localisation() {
  const [CP, setCP]= React.useState('');
  const [city, setCity]= React.useState('');
  const [ListVille, setList]= React.useState();
  const [goToExploit, setGoToExploit] = useState(false)

  useEffect ( (CP, ListVille) => {
    fetch('http://localhost:3000//api/1.0/getCommunes/'+ CP )
      .then( (response) => {
        console.log(response)
        return response.json()
      })
      .then(response =>{
        setList(response)
        console.log(response)
        console.log(ListVille)
      }) 
  })

  function handleSubmit(event) {
    event.preventDefault()
    setGoToExploit(true)
  }

  if(goToExploit) {
      return <Navigate push to={`/exploitation`} />
  }

  function handleChange(event) {
    var CP = event.target.value
    setCP(CP)      
 }

  return (
    <div>
      <Entete titre="Localisation"/>

      <form onSubmit={handleSubmit}>
        <div className='titre'> Saisissez votre code postal {CP}</div>
        <input 
        className='input'
        value={CP}
        onChange={handleChange}
        placeholder='Code Postal'
        type='text'
        required/>
        {/*<div className='paragraphe'> Test {CP==='41160' ? ListVille[0].key : 'coucou'}</div>*/}
        <div className='centrer'>
          <button type='submit' className='validation'> Valider </button>
        </div>
      </form>
    </div>
  );
}

export default Localisation;

I don't use the

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

because I want the useffect to apply everytime the CP changes

Upvotes: 1

Views: 1696

Answers (2)

MANJA1546
MANJA1546

Reputation: 11

instead of passing empty array in useEffect, pass cp state. whenever cp value changes useEffect will call that callback function.

Upvotes: 1

Mina
Mina

Reputation: 17139

First set a state in react is an asynchronous operation, so

    setList(response)
    console.log(response)
    console.log(ListVille)

console will show the old value of ListVille

If you want the current value, you can see it inside the prev value of set state.

setList(response)
console.log(response)
setList(prev => {
  console.log(prev)
  return prev;
})

Second, using useEffect without an array of dependencies will run on each component render, so if you want to call this function on the component mount, you need to set an empty array of dependencies.

Upvotes: 2

Related Questions