簡體   English   中英

有多個<select>元素在 React 中共享相同的選項?

[英]Have multiple <select> elements share the same options in React?

所以我有一個 React 組件,如:

export default function ExampleComponent() {
    return (
        <div>
            <select required name="select1">
                <option label=" "></option>
                <option value="option1">Option 1</option>
                <option value="option2">Option 2</option>
                <option value="option3">Option 3</option>
            </select>

            <select name="select2">
                <option label=" "></option>
                <option value="option1">Option 1</option>
                <option value="option2">Option 2</option>
                <option value="option3">Option 3</option>
            </select>
        </div>
    );
}

繼續進行多個選擇...

我想要它,以便當我在任何選擇標簽中選擇一個選項時,它會作為所有其他選項中的一個選項被刪除。 如果我更改選定的選項,它就會在所有其他選項中再次可用。 有誰知道我如何在 React 中做到這一點?

您必須使用state來管理值並在兩個select之間共享它。

 import React, {useState} from 'react' export default function ExampleComponent() { const [value, setValue] = useState('option0') handleChange = (e) => { setValue(e.target.value) } return ( <div> <select value={value} onChange={handleChange}> <option value="option0"></option> <option value="option1">Option 1</option> <option value="option2">Option 2</option> <option value="option3">Option 3</option> </select> <select value={value} onChange={handleChange}> <option value="option0"></option> <option value="option1">Option 1</option> <option value="option2">Option 2</option> <option value="option3">Option 3</option> </select> </div> ); }

你為什么不使用狀態? 您可以為選項使用相同的數據源,也可以為所有選擇使用相同的事件處理程序。

export default function ExampleComponent() {
  state = {
    options: [
      {
        name: 'Option 1',
        value: 'option1'
      },
      {
        name: 'Option 2',
        value: 'option2'
      },
      {
        name: 'Option 3',
        value: 'option3'
      }
    ]
  };

  onChangeSelect = event => {
    // do something
    this.setState({
      options: this.state.options.filter(
        option => option.value !== event.target.value
      )
    });
  };

  return (
    <div>
      <select required name="select1" onChange={onChangeSelect}>
        <option label=" "></option>
        {this.state.options.map(option => (
          <option value={option.value}>{option.name}</option>
        ))}
      </select>

      <select name="select2" onChange={onChangeSelect}>
        <option label=" "></option>
        {this.state.options.map(option => (
          <option value={option.value}>{option.name}</option>
        ))}
      </select>
    </div>
  );
}

可能有一種更優雅的方法來做到這一點,但我的想法是跟蹤哪個select選擇了哪個選項,並使用一個名為chosenObjects的對象,然后根據該信息過濾結果。

import React, {useState} from "react";

export default function ExampleComponent() {
    const selectNames = ["select1", "select2"];
    const [options] = useState([
        {
            label: 'Option 1',
            value: 'option1'
        },
        {
            label: 'Option 2',
            value: 'option2'
        },
        {
            label: 'Option 3',
            value: 'option3'
        }
    ]);


    const [chosenOptions, setChosenOptions] = useState({});

    const isChosenByOther = (optionValue, selectName) => {
        for (let key in chosenOptions) {
            if (key !== selectName) {
                if (chosenOptions[key] === optionValue) {
                    return true;
                }
            }
        }
        return false;
    };

    const handleChange = (ev) => {
        setChosenOptions({...chosenOptions, [ev.target.name]: ev.target.value});
    };

    return (
        <div>
            {selectNames.map((name, index) => {
                return (
                    <select name={name} key={index} onChange={handleChange} value={chosenOptions[name] || ''}
                            required={index === 0}>
                        <option value=''/>
                        {options.filter(({value}) => !isChosenByOther(value, name))
                            .map(({label, value}, oIndex) =>
                                <option value={value} key={oIndex}>{label}</option>)
                        }
                    </select>
                )
            })}
        </div>
    );
}

您還option在選擇某些內容后有條件地禁用空字符串值option

<div>
    {selectNames.map((name, index) => {
        return (
            <select name={name} key={index} onChange={handleChange} value={chosenOptions[name] || ''}
                    required={index === 0}>
                <option value='' disabled={chosenOptions[name]}>Choose Option</option>
                {options.filter(({value}) => !isChosenByOther(value, name))
                    .map(({label, value}, oIndex) =>
                        <option value={value} key={oIndex}>{label}</option>)
                }
            </select>
        )
    })}
</div>

您需要跟蹤多個Select元素的狀態,然后有條件地為每個元素渲染選項。

我將使用其他答案中的一些內容並展示如何使其工作。 編輯以保持選項的順序相同。

import React, {useState} from "react";
function ExampleComponent() {
    const [myState, setMyState] = useState({});
    const options = [
        {
            name: 'Option 1',
            value: 'option1'
        },
        {
            name: 'Option 2',
            value: 'option2'
        },
        {
            name: 'Option 3',
            value: 'option3'
        }
    ]

    // list of select names
    const selectNames = [
        "select1",
        "select2"
    ]

    handleChange = (e) => {
        // update the value for the given select
        myState[e.target.name] = e.target.value
        setMyState(myState)
    }

    const inUseValues = Object.values(myState);

      console.log(inUseValues)

    // get the options for given name
    getOptions = (name) =>
        options.filter(option => !inUseValues.includes(option.value) || myState[name]==option.value)
        .map(option => (
            <option key={option.value} value={option.value}>{option.name}</option>
        ))

    // render all select controls
    const selectRender = selectNames.map(name => (
        <select key={name} required name="{name}" value={myState[name]} onChange={handleChange}>
            <option label=" "></option>
            {getOptions(name)}
        </select>
        ))

    return (
        <div>
            {selectRender}
        </div>
    )

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM