简体   繁体   English

如何在第二个自动完成输入中获取特定数据,这取决于在 React.js 中的第一个输入中键入的内容?

[英]How to get a certain data in the second autocomplete input that depend on what typed in the first input in React.js?

Okay, so I don't know how to properly express my simple problem because of how simple it is, I guess.好的,所以我不知道如何正确表达我的简单问题,因为它很简单,我猜。

Basically, I have an autocomplete done by me in my React project.. I have two inputs "Country" and "City".基本上,我在我的 React 项目中完成了一个自动完成功能。我有两个输入“国家”和“城市”。 When I type a country my autocomplete works great giving me suggestions but now I have to make the same for my second input so it would give me a list of cities that depends on which country is typed in the "Country" input...当我输入一个国家/地区时,我的自动完成功能非常好,可以给我一些建议,但现在我必须为我的第二个输入做同样的事情,所以它会给我一个城市列表,这取决于在“国家”输入中输入的国家...

"United Kingdom" => "London, Birmingham, Bighton etc." “英国”=>“伦敦、伯明翰、拜顿等”

How can I do that?我怎样才能做到这一点? Thank you!谢谢!

PS I already have all the lists of countries and cities, I just don't know how to make the second input to depend on an information in the first one. PS我已经有了所有国家和城市的列表,我只是不知道如何使第二个输入依赖于第一个中的信息。

Code here代码在这里

Autocomplete.jsx https://github.com/lembas-cracker/Weather-app/blob/master/src/Autocomplete.jsx Autocomplete.jsx https://github.com/lembas-cracker/Weather-app/blob/master/src/Autocomplete.jsx

Form.jsx https://github.com/lembas-cracker/Weather-app/blob/master/src/Form.jsx Form.jsx https://github.com/lembas-cracker/Weather-app/blob/master/src/Form.jsx

PS I already have all the lists of countries and cities, I just don't know how to make the second input to depend on an information in the first one. PS我已经有了所有国家和城市的列表,我只是不知道如何使第二个输入依赖于第一个中的信息。

If you know which country the city belongs to (perhaps via a key in the city object), you could run a simple filter function to remove any cities that don't belong to that country.如果您知道该城市属于哪个国家/地区(可能通过 city 对象中的键),您可以运行一个简单的filter功能来删除任何不属于该国家/地区的城市。

this.state = {
    selectedCountry: 'London',
};

const cities = [
    { name: "Toronto", country: "Canada" },
    { name: "London", country: "United Kingdom" }
];

const filteredCities = cities.filter(city => {
    return city.country !== this.state.selectedCountry;
});

On your city input field make sure to create an onBlur function to will run the filter on your cities list once the user leaves that input field.在您的城市输入字段上,确保创建一个onBlur函数,以便在用户离开该输入字段后在您的城市列表上运行过滤器。

Made a quick example.做了一个简单的例子。 Did you mean smth like this?你的意思是这样的吗? Since you haven't provided any part of your source code, I used plain HTML select for the demo.由于您没有提供源代码的任何部分,因此我使用纯 HTML select进行演示。

https://jsfiddle.net/arfeo/n5u2wwjg/204186/ https://jsfiddle.net/arfeo/n5u2wwjg/204186/

class App extends React.Component {
    constructor() {
    super();

    this.state = {
        countryId: 1,
    };
  }

  onCountryChange(countryId) {
    this.setState({ countryId: parseInt(countryId) });
  }

    render() {
    return (
        <div>
        <Input
          key="countriesInput"
          type="countries"
          countryId={this.state.countryId}
          onChange={(countryId) => this.onCountryChange(countryId)}
        />
        <Input
          key="citiesInput"
          type="cities"
          countryId={this.state.countryId}
        />
      </div>
    );
  }
}

class Input extends React.Component {
    constructor() {
    super();

    this.selectRef = null;
  }

    renderOptions() {
    const countries = [
        {
        id: 1,
        name: 'England',
      },
      {
        id: 2,
        name: 'Germany',
      },
      {
        id: 3,
        name: 'France',
      },
    ];

    const cities = [
        {
        countryId: 1,
        cities: [
            {
            id: 1,
            name: 'London',
          },
            {
            id: 2,
            name: 'Liverpool',
          },
          {
            id: 3,
            name: 'Salisbury'
          }
        ],
      },
      {
        countryId: 2,
        cities: [
            {
            id: 4,
            name: 'Berlin',
          },
          {
            id: 5,
            name: 'Frankfurt',
          },
        ],
      },
      {
        countryId: 3,
        cities: [
            {
            id: 6,
            name: 'Paris',
          },
        ],
      },
    ];

    switch (this.props.type) {
        case 'countries': {
        return countries.map((country) => (
          <option
            key={country.id.toString()}
            value={country.id}
          >
            {country.name}
          </option>
        ));
      }
        case 'cities': {
        const citiesMap = cities.filter((city) => city.countryId === this.props.countryId);

        if (citiesMap && citiesMap[0]) {
            const citiesList = citiesMap[0].cities;

          if (citiesList) {
            return citiesList.map((city) => (
              <option
                key={city.id.toString()}
                value={city.id}
              >
                {city.name}
              </option>
            ));
          }
        }

        return null;
      }
      default: return null;
    }
  }

    render() {
    return (
        <select name={this.props.type} ref={(ref) => this.selectRef = ref} onChange={() => this.props.onChange(this.selectRef.value)}>
        {this.renderOptions()}
      </select>
    );
  }
}

ReactDOM.render(<App />, document.querySelector("#app"))

UPDATE更新

  1. Make your Form component stateful.使您的Form组件有状态。

  2. Add a state property for countries in Form (let it be countryId ).Form中为countries添加一个 state 属性(让它成为countryId )。

  3. Pass this property as a prop into the second Autocomplete component.将此属性作为道具传递给第二个Autocomplete组件。

  4. When the first Autocomplete changes, change the countryId of the Form .当第一个Autocomplete更改时,更改FormcountryId

I've done something similar which may help you.我做过类似的事情,可能会对你有所帮助。

The Object.keys(instutiontypes) you could use to have an array of countries, instead.您可以使用Object.keys(instutiontypes)来拥有一系列国家/地区。 Then inside of those values, you can have an array of objects.然后在这些值中,您可以拥有一个对象数组。 You could have the cities here, eg {value: "Manchester", "label: Manchester", phoneExt: "0114"}您可以在这里拥有城市,例如{value: "Manchester", "label: Manchester", phoneExt: "0114"}

const instutiontypes =  {
Kindergarten: [
    { value: "PreK", label: "PreK" },
    { value: "K1", label: "K1" },
    { value: "K2", label: "K2" },
    { value: "K3", label: "K3" },
  ],
  "Primary School": [
    { value: "Grade 1", label: "Grade 1" },
    { value: "Grade 2", label: "Grade 2" },
    { value: "Grade 3", label: "Grade 3" },
    { value: "Grade 4", label: "Grade 4" },
    { value: "Grade 5", label: "Grade 5" },
    { value: "Grade 6", label: "Grade 6" },
  ],
}

To have the options in my input, I use Object.keys(instutiontypes) to get ['Kindergarten','Primary School']为了在我的输入中有选项,我使用Object.keys(instutiontypes)来获取['Kindergarten','Primary School']

Then, to get the array of ages to give to my secondary dropdown, I have written this code:然后,为了获得要给我的辅助下拉列表的年龄数组,我编写了以下代码:

const types = ['Selection1', 'Selection2']

  const agesList = [];

  for (let i = 0; i < types.length; i++) {
    Object.values(institutionTypes[types[i]]).map(({ label }) =>
      agesList.push(label)
    );
  }

This way, the ages dropdown list is dependent on the values passed to institutionTypes .这样, ages下拉列表取决于传递给institutionTypes类型的值。

I'm using mui's <Autocomplete /> components to make them be search dropdowns, with the prop options for the arrays.我正在使用 mui 的<Autocomplete />组件使它们成为搜索下拉列表,并带有数组的 prop options

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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