根据 React.Js 中第一个下拉列表的选择填充第二个下拉列表

IT技术 javascript node.js reactjs
2021-05-20 16:36:04

我正在学习react并努力根据从第一个下拉列表中单击哪个选项来填充第二个下拉列表。

我在下面包含了我的代码。

我认为问题在于我尝试设置this.state.selected = param.tableName. 我认为这行不通,但我不确定用什么来代替。

我需要一个onClick事件来将this.state.selected变量更改为我认为选择的选项,然后检查何时tableName === selected. 我还将在下面包含我的 JSON,以便上下文更加清晰。

import React from 'react';
import axios from 'axios';
class Search extends React.Component {
    constructor(props) {
        super(props)
        this.state = {
            params: [],
            columnParams: [],
            selected: ''
        }
    }

    componentWillMount() {
        axios.get('http://localhost:3010/api/schema')
        .then( response => {
            this.setState({params: response.data})
        })
    }
    render() {
        return (
            <div className="Search">
                <select>{this.state.params.map((param, i) =>
                    <option key={i} onClick={this.setState(this.state.selected ={param.tableName})}>
                        {param.tableName}
                    </option>)}
                </select>
                <select>
                  {
                    this.state.params
                      .filter(({tableName}) => tableName === selected)
                      .map(({columns}) => columns.map((col) =><option>{col}</option>))}

[
{
"tableName": "customer",
"columns": [
"customerid",
"title",
"prefix",
"firstname",
"lastname",
"suffix",
"phone",
"email"
]
},
{
"tableName": "product",
"columns": [
"productid",
"name",
"color",
"price",
"productadjective",
"productmaterial"
]
},
4个回答

你做错了。您不能在 上调用 onClick 方法<option>相反,您应该像这样使用 onChange 方法<select>请参阅 react docs):

<select onChange={this.handleChange} >
  <option>1</option>
  <option>2</option>
  <option>3</option>
</select>

然后在“onChange”事件上,您可以将您的状态设置为所选选项。让我们通过一个例子来理解这个场景。

假设您有两个下拉列表。一个用于显示公司,一个用于与每个公司对应的工作。每家公司都有自己的一组工作,如下所示:

 companies:[
    { name: 'company1',  jobs: ['job1-1', 'job1-2', 'job1-3']},
    { name: 'company2', jobs: ['job2-1', 'job2-2', 'job2-3']},
    { name: 'company3', jobs: ['job3-1', 'job3-2', 'job3-3']}
  ]

现在您只需设置一个状态,比如说“selectedCompany”,然后通过“selectedCompany”过滤公司数组。然后,您可以通过迭代公司对象内的工作数组来获取该特定公司对象并映射您的“工作”下拉列表。

这是代码片段: https : //codepen.io/madhurgarg71/pen/pRpoMw

  1. eg 的事件处理程序onClick必须是一个函数
  2. this.setState期望一个对象,它将与状态合并,因此您selected在状态中设置的部分必须是

    <option key={i} onClick={() => {
        this.setState({selected: param.tableName})
    }>{param.tableName}}}</option>
    
  3. 您在过滤器 ( selected) 中使用了未定义的变量,您必须.filter(({tableName}) => tableName === this.state.selected)改用

需要注意的一些事项:

setState<option> onClick事件处理程序中调用的语法看起来不正确。

您还尝试this.state.selected.filter没有变量路径情况下引用您的条件 ( this.state)


建议的解决方案:

// The .setState method expects an object to be passed to it rather
// than an expression that mutates the state directly

// Pass it an object containing the properties you want to change,
// ensure your use colon (':') rather than equals sign ('=') to set property:
<option key={i} onClick={
  this.setState({
    selected: param.tableName
  })
</option>


// In the <select> tag,
// you need to refer to the selected property in it as this.state.selected:

// Don't forget the closing select tag, it's missing from your snippet
<select>
{
  this.state.params
    .filter(tableName => (tableName === this.state.selected))
    .map(columns => columns.map(col => <option>{col}</option>))
}
</select>

通过在第二个输入上将过滤器和映射链接在一起,可以轻松解决此问题,这将根据第一个下拉列表的输入过滤其选项。

            <select value={country} onChange={e => setCountry(e.target.value)}>
              {countries.map(country => (
                    <option value={country}>{country}</option>
                ))}
            </select>
            
            <select value={school} onChange={e => setSchool(e.target.value)}>
              {schools.filter(school => school.Country === country).map(school => (
                    <option value={school.Name}>{school.Name}</option>
                ))}
            </select>

上面我们有两个选择。第一个选择一个值,然后第二个的选项将基于此呈现。