在 React 中,如何更新多个选择下拉列表之间的状态,每个下拉列表都有相同的选项?

Dee*_*epi 5 javascript reactjs redux react-redux

我有一个问题,我必须渲染 4 个下拉菜单,每个下拉菜单都有类似的选项(我在这里只渲染了 1 个)。如果我在任何一个下拉列表中选择一个选项,则该选项在其他三个中不可用。

我应该如何更新该州的 selected_planets ?下面的代码从 1 个选择下拉列表更新 selected_planets。但是仍然可以在任何地方使用相同的选项,而且我无法在 selected_planets 数组中获得 4 个不同的选项?我应该如何进行?

此外,来自 API fetch 的响应是一个对象数组,我在行星数组中映射和更新。出于演示目的,让我们考虑一下行星:[海王星、土星、火星、地球、金星、木星]

import React, { Component } from 'react';

export default class Dashboard extends Component {
  state = {
    planets: [],
    selected_planets: []
  };

  componentDidMount() {
    fetch('url')
    .then(response => {
      return response.json();
    })
    .then(data => {
      this.setState({ planets: data });
    });
  }

  handleSelect = event => {
    this.setState({ selected_planets: [event.target.value] });
  };

  render() {
    let select_Planets = this.state.planets.map(planet => {
      return planet.name;
    });
    let options = select_Planets.map(planet => (
      <option key={planet} value={planet}>
        {planet}
      </option>
    ));

    return (
      <select onChange={this.handleSelect}>
        <option defaultChecked></option>
          {options}
      </select>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

Cur*_*urt 5

这可以通过根据当前选定的选项以及该下拉列表的选定选项在渲染时为每个下拉列表生成一组新选项来实现。

首先确保每个下拉列表都绑定到组件状态中的属性并在更改时更新:

  constructor() {
    super();
    this.state = {
      planets: ["a", "b", "c", "d"],
      inputs: {
        d1: "",
        d2: ""
      }
    };
    this.handleChange = this.handleChange.bind(this);
  }
Run Code Online (Sandbox Code Playgroud)
  handleChange({ target }) {
    this.setState({
      ...this.state,
      inputs: {
        ...this.state.inputs,
        [target.name]: target.value
      }
    });
  }
Run Code Online (Sandbox Code Playgroud)
<select
  name="d1"
  value={this.state.inputs.d1}
  onChange={this.handleChange}>
Run Code Online (Sandbox Code Playgroud)

render然后,您可以通过使用以下命令将输入​​对象转换为数组来获取该方法中选定行星的列表Object.values()

const selectedPlanets = Object.values(this.state.inputs);
Run Code Online (Sandbox Code Playgroud)

然后为每个下拉列表创建一个新数组,该数组将忽略已选择的任何行星,除非它是由该特定下拉列表本身选择的:

const d1Options = this.state.planets.filter(
  p => !selectedPlanets.find(sP => sP === p) || p === this.state.inputs.d1
);
const d2Options = this.state.planets.filter(
  p => !selectedPlanets.find(sP => sP === p) || p === this.state.inputs.d2
);
Run Code Online (Sandbox Code Playgroud)
<select
 name="d1"
 value={this.state.inputs.d1}
 onChange={this.handleChange}>
    <option></option>
    {d1Options.map(o => (
      <option key={o}>{o}</option>
    ))}
</select>
Run Code Online (Sandbox Code Playgroud)

我在这里整理了一个工作示例:

https://codepen.io/curtis__/pen/pozmOmx


xde*_*akv 2

您可以通过多种方式解决这个问题。这是伪代码。创建一个对象或数组来保存所选索引的值。我建议使用 useState API。而不是 setState。

class extends Component {
  static state = {
    dropdown1: "",
    dropdown2: "",
    dropdown3: "",
    dropdown4: ""
  }
  constructor(props) {
    super(props)
  }
  handleClick = (id, {target: {value}}) => {
    this.setState({
      [id]: value
    })
  }
  render()  {
    <div>
      <select onChange={this.handleClick.bind(null, "dropdown1")}>

      </select>
      <select onChange={this.handleClick.bind(null, "dropdown2")}>

      </select>
      <select onChange={this.handleClick.bind(null, "dropdown3")}>

</select>
<select onChange={this.handleClick.bind(null, "dropdown4")}>

</select>
    </div>
  }

}
Run Code Online (Sandbox Code Playgroud)