最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Populate 2nd dropdown based on selection from 1st dropdown in React.Js - Stack Overflow

programmeradmin1浏览0评论

I am learning react and struggling to get a second dropdown to populate based on which option is clicked from first dropdown.

I have included my code below.

I think the issue is where I try to set this.state.selected = param.tableName. I don't think that will work, but I'm not sure what to use instead.

I need an onClick event to change the this.state.selected variable to the option that is selected I think, and then check when tableName === selected. I will also include my JSON below so the context is more clear.

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

    ponentWillMount() {
        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"
]
},

I am learning react and struggling to get a second dropdown to populate based on which option is clicked from first dropdown.

I have included my code below.

I think the issue is where I try to set this.state.selected = param.tableName. I don't think that will work, but I'm not sure what to use instead.

I need an onClick event to change the this.state.selected variable to the option that is selected I think, and then check when tableName === selected. I will also include my JSON below so the context is more clear.

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

    ponentWillMount() {
        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"
]
},
Share Improve this question edited Jan 7, 2019 at 7:57 jww 102k103 gold badges443 silver badges944 bronze badges asked Jan 29, 2017 at 1:49 AlexAlex 531 gold badge2 silver badges8 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 3

You're doing it wrong way. You cannot call onClick method on <option>. Instead you should use onChange method on <select> (see react docs) like this:

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

Then on 'onChange' event you can set your state to the selected option. Let's understand this scenario with an example.

Suppose you have two dropdowns. One for showing panies and one for jobs corresponding to each pany. Each pany has its own set of jobs like this:

 panies:[
    { name: 'pany1',  jobs: ['job1-1', 'job1-2', 'job1-3']},
    { name: 'pany2', jobs: ['job2-1', 'job2-2', 'job2-3']},
    { name: 'pany3', jobs: ['job3-1', 'job3-2', 'job3-3']}
  ]

Now you have to just set a state, lets say 'selectedCompany' and then filter the panies array by 'selectedCompany'. Then you can just get that particular pany object and map your 'jobs' dropdown by iterating over jobs array inside the pany object.

Here is the code snippet: https://codepen.io/madhurgarg71/pen/pRpoMw

  1. event handlers for e.g. onClick must be a function
  2. this.setState expects an object, which will be merged with the state so the part where you set selected in your state must be

    <option key={i} onClick={() => {
        this.setState({selected: param.tableName})
    }>{param.tableName}}}</option>
    
  3. you use an undefined variable in your filter (selected), you have to use .filter(({tableName}) => tableName === this.state.selected) instead

Some things to look at:

The syntax in your call to setState in your <option> onClick event handler looks incorrect.

You also make try to reference this.state.selected in your .filter condition without the path to the variable (this.state)


Suggested solution(s):

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

This issue can easily be dealt with by chaining a filter and map together on the second input, which filters it's options depending on the input of the first drop down.

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

Above we have two selects. The first selects a value, and then the options for the second will render based on this.

发布评论

评论列表(0)

  1. 暂无评论