使用一个主下拉菜单实现多个下拉菜单

Zha*_*Zha 5 javascript drop-down-menu reactjs

我正在使用PrimeReact. 我必须实现它们,以便第一个上部主下拉列表中的值 ?? 更改所有下部主下拉列表的值,我已经这样做了,但是我需要比来自下部块的每个动态下拉列表都必须更改更改其独特价值:

截屏

我无法理解如何实现它。

这是我的代码:

    class LeagueCard extends Component {

  state = {
    selectedItemDefaultDropDown: this.props.cardContent.insuranceVariants[0],
    selectedItemPersonallyDropDown: null
  };

  createOptions = (arr) => {
    return arr.map(item => ({label: item, value:item}))
  };


  render() {
    const {
      cardIndex, cardContent: {
        insuranceVariants,
        price,
      },
    } = this.props;


    const insuranceOptions = this.createOptions(insuranceVariants);


    return (
        <>
          <div className={styles.header}>
            <h4>League {cardIndex + 1}</h4>
            <h4>Total {price.reduce((a, b) => a + b)} PLN</h4>
          </div>
          <div className={styles.defaultDropDownWrapper}>
            <p>Default variant of the insurance program</p>
            <Dropdown //MAIN DROPDOWN WORKS PERFECTLY
                value={this.state.selectedItemDefaultDropDown}
                options={insuranceOptions}
                onChange={e => {
                  this.setState({ selectedItemDefaultDropDown:e.value });
                }}
            />
          </div>
          <table>
            <thead>
            <tr>
              <th className={styles.columnName}>#</th>
              <th className={styles.columnName}>FIRST AND LAST NAME</th>
              <th className={styles.columnName}>AGE</th>
              <th className={styles.columnName}>VARIANT OF THE INSURANCE PROGRAM</th>
            </tr>
            </thead>
            <tbody>
            {insuranceVariants.map((item, index) =>
                <tr key={index} className={(index + 1) % 2 === 0 ? styles.evenTabStyle : styles.baseTabStyle}>
                  <td>{index + 1}</td>
                  <td>Jan Nowak</td>
                  <td>20</td>
                  <td>
                    <Dropdown //SECONDARY DYNAMICALLY DROPDOWNS WITH TROUBLES
                        value={this.state.selectedItemDefaultDropDown}
                        options={insuranceOptions}
                        onChange={e => {
                          this.setState({ selectedItemDefaultDropDown: e.value});
                        }}
                    />
                  </td>
                </tr>)}
            </tbody>
          </table>
        </>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Tri*_*kar 4

有多种方法可以实现此目的,但我现在能想到的最简单的方法是以下

因为您有 3 个下拉菜单(在本例中),所以您需要为每个下拉菜单保留 3 个条目的状态

保持你的状态是这样的

{
  primaryDropdown: 'selected option',
  secondaryDropdowns: ['selected value for first', 'selected value for second']
}
Run Code Online (Sandbox Code Playgroud)

我保留数组是因为您可以动态更改辅助下拉列表的数量

现在onChangeHandler主要下拉列表将如下所示

primaryOnChangeHander(selected) {
 this.setState(prevState => {
  const newState = { 
    ...prevState,
    primaryDropdown: selected,
    secondaryDropdowns: prevState.secondaryDropdowns.map(item => selected )
  };
  return newState;
 })
}
Run Code Online (Sandbox Code Playgroud)

当主要下拉列表更改时,您也将更新主要下拉列表和辅助下拉列表

对于onChangeHander二级下拉菜单看起来像

 secondaryOnChangeHander (selected, indexOfDropdown) {
  this.setState(prevState => ({
    ...prevState,
    secondaryDropdowns: prevState.secondaryDropdowns.map((item, index) => {
      if (index === indexOfDropdown) {
        return selected;
      } else {
       return item;
      }
    })
  }))
}
Run Code Online (Sandbox Code Playgroud)

当辅助下拉列表值更改时,您仅更新该特定下拉列表值


你的代码现在看起来像这样

/* important note here: assuming that insuranceVariants is a fixed length array */
class LeagueCard extends Component {

  state = {
    /* better would be to create a variable for `this.props.cardContent.insuranceVariants[0]` and use that */
    primaryDropdown: this.props.cardContent.insuranceVariants[0],
    secondaryDropdowns: [this.props.cardContent.insuranceVariants.map(item => this.props.cardContent.insuranceVariants[0]]
  };

  createOptions = (arr) => {
    return arr.map(item => ({label: item, value:item}))
  };

  primaryOnChangeHander(selectedValue) {
    this.setState(prevState => {
      const newState = { 
        ...prevState,
        primaryDropdown: selectedValue,
        secondaryDropdowns: prevState.secondaryDropdowns.map(item => selectedValue)
      };
      return newState;
    })
  }

  secondaryOnChangeHander (selectedValue, indexOfChangedDropdown) {
    this.setState(prevState => ({
      ...prevState,
      secondaryDropdowns: prevState.secondaryDropdowns.map((item, index) => {
        if (index === indexOfChangedDropdown) {
          return selectedValue;
        } else {
          return item;
        }
      })
    }));
  }

  render() {
    const {
      cardIndex, cardContent: {
        insuranceVariants,
        price,
      },
    } = this.props;


    const insuranceOptions = this.createOptions(insuranceVariants);


    return (
      <>
        <div className={styles.header}>
          <h4>League {cardIndex + 1}</h4>
          <h4>Total {price.reduce((a, b) => a + b)} PLN</h4>
        </div>
        <div className={styles.defaultDropDownWrapper}>
          <p>Default variant of the insurance program</p>
          <Dropdown //MAIN DROPDOWN WORKS PERFECTLY
            value={this.state.primaryDropdown}
            options={insuranceOptions}
            onChange={e => {
              this.primaryOnChangeHander(e.value);
            }}
          />
        </div>
        <table>
          <thead>
            <tr>
              <th className={styles.columnName}>#</th>
              <th className={styles.columnName}>FIRST AND LAST NAME</th>
              <th className={styles.columnName}>AGE</th>
              <th className={styles.columnName}>VARIANT OF THE INSURANCE PROGRAM</th>
            </tr>
          </thead>
          <tbody>
            {insuranceVariants.map((item, index) =>
            <tr key={index} className={(index + 1) % 2 === 0 ? styles.evenTabStyle : styles.baseTabStyle}>
              <td>{index + 1}</td>
              <td>Jan Nowak</td>
              <td>20</td>
              <td>
                <Dropdown //SECONDARY DYNAMICALLY DROPDOWNS WITH TROUBLES
                  value={this.state.secondaryDropdowns[index]}
                  options={insuranceOptions}
                  onChange={e => {
                    this.secondaryOnChangeHander(e.value, index);
                  }}
                />
              </td>
            </tr>)}
          </tbody>
        </table>
      </>
    );
  }
}

Run Code Online (Sandbox Code Playgroud)