ReactJs中国家和州的动态下拉列表

问题描述

如何在ReactJs的select标记内呈现选项?

我有一个用于国家和州的json数据。我想与所选国家/地区一起动态显示选择标记中的状态。

const onCountryChange = value => {
    const country = value.split("_")[0];
    const countryCode = value.split("_")[1];
    const countryId = value.split("_")[2];
    setCountry(country);
    setCountryCode(countryCode);
    setCountryId(countryId)
  };

选择国家标签

<select value={country} onChange={e => onCountryChange(e.target.value)}>
     <option value="" disabled>Select Country</option>
     {
         COUNTRIES.map((country,index) => {
                            return (
                              <option
                                key={index}
                                value={country.name + "_+" + country.phoneCode + "_" + country.id}
                              >
                                {country.name}
                              </option>
                            );
                          })
     }
</select>

选择状态标签

<select value={state} onChange={e => onStateChange(e.target.value)} >
     <option value="" disabled>Select State/Province</option>
     {
       STATES.filter(states => (states.country_id === countryId)).map((state,index) => {
                            console.log(state.name)
                            return (
                              <option
                                key={index}
                                value={state.name + "_+" + state.id}
                              >
                                {state.name}
                              </option>
                            );
                          })
     }                          
</select>

下拉至国家/地区即可正确渲染。当我选择一个国家/地区时,相应的国家/地区不会在选择标记中呈现,因为状态会显示在控制台中。

解决方法

没有看到更多代码,我无法完全回答您的问题,但是我提供了一个基本的工作片段,该片段使用简单的可重复使用的Select组件,并使用来存储所选国家和地区的ID useState

此外,您的代码中存在一些显着的低效率,如果您解决这些问题,将会使所有内容更具可读性,并且可能有助于避免或更容易发现行为或输出错误。

首先,在编写两个单独的select元素时有很多重复,通过从它们内部返回,您会变得更加复杂。这是抽象到单独组件的好时机。

function Select({ options,value,title,handleSelectChange }) {

  return (
    <select name="title" value={value ? value : ''} onChange={handleSelectChange} >
      <option value="" disabled selected hidden>{title}</option>
      {options.map(option =>
        <option key={option.id} value={option.id}  >
          {option.name}
        </option>
      )}
    </select>
  )
}

接下来,您要在onChange中声明一个匿名函数来调用命名函数,并且仅传递event。可以通过直接引用来调用React中的命名函数,这些函数将被固有地传递给事件,因此您可以简化代码:

const onCountryChange = (event) => {
   console.log(event.target.value);
...
}

<select ... onChange={onCountryChange}>

onCountryChange中,有很多重复项(并且对同一字符串的split进行了三个调用)。您可以使用destructuring assignment来简化此操作

const onCountryChange = (e) => {
    const [country,countryCode,countryId] = e.target.value.split("_");
}

这些都是小指针,但尽可能地学习基础知识和编码将有助于避免混乱。

<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<div id="App"></div>
<script type="text/babel">
  const { useState} = React;

const countries = [
  { id: 'AD',name: 'Andorra' },{ id: 'AE',name: 'United Arab Emirates' },{ id: 'AF',name: 'Afghanistan' },{ id: 'AG',name: 'Antigua and Barbuda' },{ id: 'AI',name: 'Anguilla' },]

const states = [
  { id: 'ad1',name: 'AD: State 1',countryId: 'AD' },{ id: 'ad2',name: 'AD: State 2',{ id: 'ad3',name: 'AD: State 3',{ id: 'st1',name: 'AI: State 4',countryId: 'AI' },{ id: 'st2',name: 'AI: State 5',{ id: 'st3',name: 'AI: State 6',{ id: 'ag1',name: 'AG: State 7',countryId: 'AG' },{ id: 'ag2',name: 'AG: State 8',{ id: 'ag3',name: 'AG: State 9',{ id: 'af1',name: 'AF: State 10',countryId: 'AF' },{ id: 'af2',name: 'AF: State 11',{ id: 'af3',name: 'AF: State 12',{ id: 'ae1',name: 'AE: State 13',countryId: 'AE' },{ id: 'ae2',name: 'AE: State 14',{ id: 'ae3',name: 'AE: State 35',countryId: 'AE' }
]

function Select({ options,handleSelectChange }) {

  return (
    <select name="title" value={value ? value : ''} onChange={handleSelectChange} >
      <option value="" disabled selected hidden>{title}</option>
      {options.map(option =>
        <option key={option.id} value={option.id}  >
          {option.name}
        </option>
      )}
    </select>
  )
}

function App() {
  const [selectedCountryId,setSelectedCountryId] = useState(null);
  const [selectedStateId,setSelectedStateId] = useState(null);

  const handleCountryChange = (e) => {
    setSelectedStateId(null);
    setSelectedCountryId(e.target.value);
  }

  const handleStateChange = (e) => {
    setSelectedStateId(e.target.value);
  }

  return (
  <div>
    <div className="select-container">
      <Select 
        options={countries} 
        value={selectedCountryId} 
        title='Select Country' 
        handleSelectChange={handleCountryChange} 
      />
      <Select 
        options={states.filter(state => 
        state.countryId === selectedCountryId)} 
        value={selectedStateId} 
        title='Select State/Province'
        handleSelectChange={handleStateChange} 
      />
    </div>
    <div class='output'>
      <p>Selected Country Id: {selectedCountryId}</p>
      <p>Selected State Id: {selectedStateId}</p>
    </div>
   </div>
  )

}

ReactDOM.render(<App />,document.getElementById('App'));

 </script>