Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

147
Visualizações
Trouble to fill a dropdown menu using react

I have some problems with a project. I want to display some data, that I retreive from an API, in a dropdown menu. I used the .map() function and jsx to display everything, but nothing is working, the dropdown menu stay empty whereas a console.log(cities) show me that my array is filled.

function CitiesList(){
  var cities = citiesRequest();
  return (
    <form id="cityChoice">
      <label for="citySelected">Ville : </label>
      <select name="citiesList" id="citySelected">
        {cities.map((city) => <option key={city} value={city}>{city}</option>)}
      </select>
    </form>
  );
} 

If I change the way "cities" is fill for test, everything is working and the dropdown menu is filled :

function CitiesList(){
  var cities = ["Berlin", "Paris", "London"];
  return (
    <form id="cityChoice">
      <label for="citySelected">Ville : </label>
      <select name="citiesList" id="citySelected">
        {cities.map((city) => <option key={city} value={city}>{city}</option>)}
      </select>
    </form>
  );
} 

Here is entire my code if that can help :

function Header(props){
  return(
    <header>
      <h1 className="apiTitle">{props.name}</h1>
      <CitiesList/>       
    </header>
  );
}

function CitiesList(){
  var cities = citiesRequest();
  return (
    <form id="cityChoice">
      <label for="citySelected">Ville : </label>
      <select name="citiesList" id="citySelected">
        {cities.map((city) => <option key={city} value={city}>{city}</option>)}
      </select>
    </form>
  );
} 

ReactDOM.render(
  <Header name="Bike Mapper"/>,
  document.getElementById('root')
);
  
function citiesRequest(){
  var citiesArray = [];
  fetch("https://api.jcdecaux.com/vls/v3/contracts?apiKey="+APIKEY)
    .then((response) => response.json())
    .then(function(data){
    data.forEach(element => {
      if(element.country_code == 'FR'){
        citiesArray.push(element.name.toUpperCase());
      }
    }); 
  })
  return citiesArray;
}

Thanks

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Your city array is always empty because you are not waiting for the API to send the response back. To achieve this you can use Promises

function Header(props){
  return(
    <header>
      <h1 className="apiTitle">{props.name}</h1>
      <CitiesList/>       
    </header>
  );
}

async function CitiesList(){
  var cities = await citiesRequest();
  return (
    <form id="cityChoice">
      <label for="citySelected">Ville : </label>
      <select name="citiesList" id="citySelected">
        {cities.map((city) => <option key={city} value={city}>{city}</option>)}
      </select>
    </form>
  );
} 

ReactDOM.render(
  <Header name="Bike Mapper"/>,
  document.getElementById('root')
);
  
async function citiesRequest(){
  return new Promise((resolve,reject)=>{
   var citiesArray = [];
   fetch("https://api.jcdecaux.com/vls/v3/contracts?apiKey="+APIKEY)
     .then((response) => response.json())
     .then(function(data){
      data.forEach(element => {
        if(element.country_code == 'FR'){
          citiesArray.push(element.name.toUpperCase());
        }
       }); 
      resolve(citiesArray);
   })
   
  })
}

Using Hooks

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

function Header(props){
  const [cities, setCities] = useState([])
  useEffect(()=>{
     citiesRequest().then(data=>{
       setCities(data)
     });
   },[])
  return(
    <header>
      <h1 className="apiTitle">{props.name}</h1>
      <form id="cityChoice">
      <label for="citySelected">Ville : </label>
      <select name="citiesList" id="citySelected">
        {cities.map((city) => <option key={city} value={city}>{city} 
      </option>)}
      </select>
    </form>     
    </header>
  );
}   
ReactDOM.render(
  <Header name="Bike Mapper"/>,
  document.getElementById('root')
);
  
async function citiesRequest(){
  return new Promise((resolve,reject)=>{
   var citiesArray = [];
   fetch("https://api.jcdecaux.com/vls/v3/contracts?apiKey="+APIKEY)
     .then((response) => response.json())
     .then(function(data){
      data.forEach(element => {
        if(element.country_code == 'FR'){
          citiesArray.push(element.name.toUpperCase());
        }
       }); 
      resolve(citiesArray);
   })
   
  })
}
about 4 years ago · Juan Pablo Isaza Relatório

0

I think the problem is that by the time that data is returned from your citiesRequest function, the component rendered already and has no indication that it should re-render.

You can try to:

  • modify citiesRequest function to return the data directly
  • call it within useEffect (with empty dependency array - to call it just once when the component mounts) in your component
  • await the response and then set it to component state (setCities).

When state changes, React will know it should re-render.

function CitiesList(){
  const [cities, setCities] = useState([]);

  useEffect(() => {
    const getData = async () => {
      const data = await citiesRequest();
      setCities(data);
    }
    
    getData();
  }, [])

  return (
    <form id="cityChoice">
      <label for="citySelected">Ville : </label>
      <select name="citiesList" id="citySelected">
        {cities.map((city) => <option key={city} value={city}>{city}</option>)}
      </select>
    </form>
  );
} 
  
function citiesRequest(){
  return fetch("https://api.jcdecaux.com/vls/v3/contracts?apiKey="+APIKEY)
    .then((response) => response.json())
    .then(function(data){ 
      return data
    })
}

about 4 years ago · Juan Pablo Isaza Relatório

0

using useState useEffect to have the page re-render on cities state change

function CitiesList(){
  const [cities, setCities] = React.useState([])

 React.useEffect(()=>{
  if(!cities.length){
   citiesRequest().then(result=>setCities(result)).catch(console.log)
  }
 },[cities])

  return (
    <form id="cityChoice">
      <label for="citySelected">Ville : </label>
      <select name="citiesList" id="citySelected">
        {cities.map((city) => <option key={city} value={city}>{city}</option>)}
      </select>
    </form>
  );
} 

function citiesRequest(){
 return new Promise((resolve, reject)=>{
  var citiesArray = [];
  fetch("https://api.jcdecaux.com/vls/v3/contracts?apiKey="+APIKEY)
    .then((response) => response.json())
    .then(function(data){
    data.forEach(element => {
      if(element.country_code == 'FR'){
        citiesArray.push(element.name.toUpperCase());
      }
    }); 
  }).catch(err=>reject(err))
  resolve(citiesArray);
 })
}
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda