【问题标题】:Populate 2nd dropdown based on selection from 1st dropdown in React.Js根据 React.Js 中第一个下拉列表的选择填充第二个下拉列表
【发布时间】:2017-01-29 01:49:33
【问题描述】:

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

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

我认为问题在于我尝试设置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"
]
},

【问题讨论】:

    标签: javascript node.js reactjs


    【解决方案1】:

    你做错了。您不能在 &lt;option&gt; 上调用 onClick 方法。相反,您应该像这样在&lt;select&gt; (see react docs) 上使用 onChange 方法:

    <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”过滤公司数组。然后,您可以通过迭代公司对象内的作业数组来获取该特定公司对象并映射您的“工作”下拉列表。

    这里是sn-p的代码: https://codepen.io/madhurgarg71/pen/pRpoMw

    【讨论】:

    • 这正是我所寻求的,效果很好,谢谢!
    • codepen.io/madhurgarg71/pen/pRpoMw 但是如何在选择框只是其他字段中的字段的页面中使用它?我的网页是一个扩展了 react Component 的类。
    【解决方案2】:
    1. 事件处理程序,例如onClick 必须是函数
    2. this.setState 需要一个对象,该对象将与状态合并 所以你在你的状态中设置selected的部分必须是

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

    【讨论】:

      【解决方案3】:

      需要注意的事项:

      您在&lt;option&gt; onClick 事件处理程序中调用setState 的语法看起来不正确。

      您还尝试在您的 .filter 条件中引用 this.state.selected 而不使用变量路径 (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>
      

      【讨论】:

        【解决方案4】:

        这个问题可以很容易地通过在第二个输入上链接一个过滤器和映射来解决,它根据第一个下拉菜单的输入过滤它的选项。

                    <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>
        

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

        【讨论】:

          猜你喜欢
          • 2012-01-04
          • 1970-01-01
          • 2017-12-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-06
          • 2017-04-06
          • 1970-01-01
          相关资源
          最近更新 更多