简体   繁体   中英

React JS multi-country state dropdown menu

I am trying to map over an array to create a dropdown menu with multiple countries and their associated states. My array looks like the following (short version to save time/length):

[
    {
        "country" : "USA",
        "states" : {
            "name" : ["Alabama", "Alaska"],
            "value" : ["AL", "AK"]
        }
    },
    {
        "country" : "Mexico",
        "states" : {
            "name" : ["Aguascalientes", "Baja California"],
            "value" : ["AG", "BC"]
        }
    }


]

and I tried to do the following:

import React from 'react';
import data from './allstates.json';

const StateDrop = () => {

    return (
        <div >
            <select>
                 {data.map(item => (
                    <optgroup label={item.country}>
                        <option key={item.states.name} value={item.states.value}>{item.states.name}</option>
                    </optgroup>
                ))}
            </select> 
        </div>
     );
}
 
export default StateDrop;

But it lists all the names in one option. I tried to use the spread operator on the names but it says that spread children are not allowing in React.

I know that I could just make 3 lists of my states data and map over those arrays under their own optgroup div, but I wanted to know if there is a way to accomplish this similar to my current approach? I could find json object with nested arrays but not any solid information here or otherwise to point me in the direction of a solution. My first thought was to throw the names into their own array using the spread operator but this didn't work. Any advice would be super helpful. I thought maybe I needed to have useState and add the countries/states there but I couldn't see how that was any different.

Is this what you are aiming for?

  export default function App() {
  return (
    <div>
      <select>
        {data.map(item => (
          <optgroup key={item.country} label={item.country}>
            {item.states.name.map((x, i) => (
              <option key={x} value={item.states.value[i]}>
                {x}
              </option>
            ))}
          </optgroup>
        ))}
      </select>
    </div>
  );
}

it assumes that within a country, the i-th value corresponds to i-th name though. If you restructure your data you can make code cleaner though: if you turn item.states into array of objects of the form: {name, value} , it will become easier to render options .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM