Mandoxsy
Mandoxsy

Reputation: 103

React - How to Populate one Dropdowns based on selection from another Dropdown by Passing State as props

I am creating a bar with two dropdown. The second dropdown depends of the selection from the first dropdown. I have 3 Components : 1. Dropdown Bar : Contains FirstDropdown and Second Dropdown 2. FirstDropdown 3. SecondDropdown

Trying to pass State -> Practice that appears in the FirstDropdown Component as props to SecondDropdown Component. Clearly I'm not doing this correctly. Any Help will be appreciate. Thank you in advance!

class DropdownBar extends React.Component {
constructor(props) {
    super(props);
}

render () {
    return (
        <div>
            <div className="top-bar">
                <Row>
                    <div style={{marginTop: 15, marginBottom:15}}>
                        <Col span={8}><FirstDropdown practice={this.props.practice} /></Col>
                        <Col span={8}><SecondDropdown /></Col> 

                    </div>
                </Row>
            </div>
        </div>
    )
}





class FirstDropdown extends React.Component {
constructor() {
    super();
    this.state = {
        practices: [
            name = 'Jon',
            name = 'potato',
            name = 'stark',
        ],
        practice: 'stark'
    }
}

onChangePractice(value) {
    console.log(`selected ${value}`);
    this.setState({
        practice: value
    })
}


render () {
    const {practices} = this.state

    return  (
        <div>
            <Row>
                <div className="First-dropdown">
                <Col span={8}><div className="dropdown-title">Research: </div></Col>
                <Col span={14}>
                    <Select
                    showSearch
                    style={{ width: '100%' }}
                    placeholder="Select a Something"
                    optionFilterProp="children"
                    onChange={this.onChangePractice.bind(this)}
                    onFocus={onFocus}
                    onBlur={onBlur}
                    onSearch={onSearch}
                    filterOption={(input, option) =>
                    option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                    }
                    >
                        {practices.map(practice => (
                            <Option
                            value={practice}
                            key={practice}
                            data-automation={practice.name}
                            >{practice}</Option>
                        ))}
                    </Select>                   
                </Col>
                </div>
            </Row>
        </div>

    )
}



class SecondDropdown extends React.Component {
constructor(props) {
    super(props);
    this.state = {
        modules: [
            name = 'Drogon',
            name = 'Rhaegal',
            name = 'Viserion',
        ]
    }
}
componentDidUpdate(prevProps) {
    console.log(this.props.practice)
    if (!equal(this.props.practice, prevProps.practice)) 
    {
        this.updatePractice();

    }
} 

render () {
    const {modules} = this.state
    console.log(this.props.practice )
    let practice = this.props.practice;

    if (practice === 'stark') {
        return  (
            <div>
                <Row>
                    <div className="benchmark-dropdown">
                    <Col span={4}><div className="dropdown-title">Module: </div></Col>
                    <Col span={16}>
                        <Select
                        showSearch
                        style={{ width: '100%' }}
                        placeholder="Select Something"
                        optionFilterProp="children"
                        onChange={onChange}
                        onFocus={onFocus}
                        onBlur={onBlur}
                        onSearch={onSearch}
                        filterOption={(input, option) =>
                        option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
                        }
                        >
                            {modules.map(item => (
                                <Option
                                value={item}
                                key={item}
                                >{item}</Option>
                            ))}
                        </Select>                   
                    </Col>
                    </div>
                </Row>
            </div>

        )
    } else {
        return <div> NOOOOO </div>
    }

}

Upvotes: 2

Views: 10928

Answers (2)

helloitsjoe
helloitsjoe

Reputation: 6529

In order for both dropdowns to have access to the practice prop, you need to lift it up to the DropdownBar's state, and pass down both practice and a way to update practice.

class DropdownBar extends Component {
  state = {
    practice: '',
  }

  handlePracticeChange = (value) => {
    setState({ practice: value });
  }

  render() {
    return (
      <div>
        <FirstDropdown
          practice={this.state.practice}
          onPracticeChange={this.handlePracticeChange}
        />
        <SecondDropdown practice={this.state.practice} />
      </div>
    )
  }
}

So, practice only lives in DropdownBar, and the practices array should live in FirstDropdown child.

In FirstDropdown, you should pass props.onPracticeChange to your Select's onChange:

class FirstDropdown extends Component {
  render() {
    ...
    <Select
      onChange={this.props.onPracticeChange}
    ...
  }
}

From your code example, it looks like Select passes the currently selected value to onChange.

Upvotes: 2

Anthony Z
Anthony Z

Reputation: 394

I'd pull the state into the parent.

class MainBar extends React.Component {
  state = {
    practice: null
  };
  
  handleChange = practice => {
    this.setState({ practice });
  }
  
  render() {
    return (
      <div className="top-bar">
        <Row>
          <div style={{marginTop: 15, marginBottom:15}}>
              <Col span={8}>
                <FirstDropdown 
                  onChange={this.handleChange}
                  practice={this.state.practice}
                />
              </Col>
              <Col span={8}>
                <SecondDropdown practice={this.state.practice} />
              </Col> 
          </div>
        </Row>
      </div>
    );
  }
}

Upvotes: 0

Related Questions