【问题标题】:React-select multiple drop downs onChange implementationReact-select 多个下拉 onChange 实现
【发布时间】:2021-08-28 05:02:57
【问题描述】:

使用 react-select 在我的 Mongo 中实现了一个基于数组字段的动态下拉菜单,就像这样。

    import React, { useState } from 'react'
import Select from 'react-select'


  const NonFormikSelect = (props) => {

    const [selectedOptions, setSelectedOptions] = useState([])

        let options1 = props.member.members.map(member => ({
            label: member.MemberName,
            value: member.MemberName
        }))

        console.log(options1)

      const selectChangeHandler = (event, numberofgroups) => {
       
      }

          const newValues = props.nogot.tournament.TournamentGroups.map((numberofgroups) => {
        return (
            <Select
            key={numberofgroups}
            name={numberofgroups}
            isMulti
            options={options1}
            value={numberofgroups in selectedOptions ? selectedOptions[numberofgroups]: ""}
            onChange={(event) => selectChangeHandler(event, numberofgroups)}
             />         
        )
    })

    return (
        newValues
    )
      }

  export default NonFormikSelect

我的难题在于更改处理函数。我尝试了多个组合并浏览了多个文档,但无法破解我想要的设计。这是我在这个组件中的状态声明

const [selectedOptions, setSelectedOptions] = useState([])

这是我想要的 onChange 功能。

假设 - 我的 map 函数的输入数组有 2 个元素,因此这意味着 2 个选择下拉列表将被推送到前端,下拉列表中的值将来自另一个 options1 对象。正如 react-select 所期望的那样,这有一个标签和值键对。假设对象内部有 10 个键值对。

当用户打开表单时,他会看到 2 个下拉菜单。如果他在第一个下拉列表中选择 3 个名称,那么我希望这些名称从第二个下拉列表中删除。在第二个下拉列表中,假设他选择了。然后需要将所有 8 个值提升到父组件,在那里我正在获取 API 并更新我的集合。

这可行吗?我已经没有想法了。我的更改处理函数现在是空的,因此这里没有发布任何内容

【问题讨论】:

  • 所以你想有条件地从第二个数组的值中过滤掉一个选择数组的先前值?
  • 是的,先生,如果可能的话。我的第一个选择是“John”、“Joe”和“Joel”。我选择约翰。所以下一个选择应该只有 Joe 和 Joel。当我点击提交时。两个选择项的用户选择的所有值都应推送到父项
  • 所以第一个选择是整个数组,然后第二个选择只是第一个未使用的值?
  • 是的,先生,这就是愿望
  • 您是在 React 中还是在 HTML 中生成选择字段?

标签: reactjs react-select


【解决方案1】:

您正在寻找的是级联选择。

import "./styles.css";
import Select from "react-select";
import { useState } from "react";

const allOptions = [
  {
    label: "john",
    value: 1
  },
  {
    label: "joe",
    value: 2
  },
  {
    label: "joel",
    value: 3
  },
  {
    label: "jackie",
    value: 4
  }
];

const generateInitialState = (numberOfSelects) =>
  numberOfSelects.map((item) => null);

const CustomSelectComponent = ({ value, options, onSelect }) => {
  return (
    <Select
      value={value}
      options={options}
      isMulti
      onChange={onSelect}
    />
  );
};

export default function App() {
  const [selectState, setSelectState] = useState(() =>
    // increase the array elements to add more select fields
    generateInitialState(["Group1", "Group2", "Group3"])
  );

  const onSelectValues = (value, index) => {
    // clone state
    const clonedSelectState = JSON.parse(JSON.stringify(selectState));

    clonedSelectState[index] = value;
    setSelectState(clonedSelectState);
  };

  return (
    <div className="App">
      {selectState.map((selectCount, index) => {
        const options = getOptionsToRender(selectState, allOptions);
        return (
          <CustomSelectComponent
            value={selectState[index]}
            options={options}
            onSelect={(value) => onSelectValues(value, index)}
            key={index}
          />
        );
      })}
    </div>
  );
}

const getOptionsToRender = (allSelectedOptions, allOptions) => {
  // convert [[{}, {}], [{}]] -> [{}, {}, {}]
  const filteredOptions = allSelectedOptions.flatMap((options) => options);

  const optionsToRender =
    filteredOptions.length > 0
      ? allOptions.filter(
          (option) =>
            !filteredOptions.some(
              (selectOption) =>
                option && selectOption && option.value === selectOption.value
            )
        )
      : allOptions;

  return optionsToRender;
};

Cascading Select Example

【讨论】:

  • 所以只是建立在 Shyam 的基础上,就像我说的那样,选择项的数量取决于通过 props 传入的数组的长度。我将如何应对不断变化的动态大小数组?
  • 可以添加动态数组的形状吗?
  • 它是一个简单的数组,例如 ["Group 1", "Group 2"]。但是数组中的值可以是 ["Group 1] 或者可以是 ["Group 1", "Group 2", "Group 3"]。所有这些都来自我已经构建的上游管理表单。我正在映射这个数组并根据此数组中的元素数量,我想要显示的 Select 项目数
  • 用一个工作示例编辑了我的答案和沙箱。
  • 我花了大约 2 个小时来理解和实施它@shyam,但它就像做梦一样 :)。谢谢一吨
猜你喜欢
  • 1970-01-01
  • 2018-11-11
  • 1970-01-01
  • 2015-07-19
  • 1970-01-01
  • 2023-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多