如何正确更新在React中?

问题描述 投票:0回答:1

在React应用中,您应该控制<select>。只需选择一个,这真的很容易:

const ExampleSelect = () => {
  const [value, setValue] = React.useState()
  return (
    <select
      value={value}
      onChange={(e) => setValue(e.currentTarget.value)}
    >
      <option value='foo'>Foo</option>
      <option value='bar'>Bar</option>
      <option value='baz'>Baz</option>
    </select>
  )
}

但是将multiple道具添加到<select>时,事情会变得很奇怪。传递给onChange的功能会迭代选项并根据只有option.selected === true的功能来执行操作,这些功能似乎仅可在桌面上使用-在iOS的Safari中,似乎无法控制multiple === true的选择。

我觉得这是一个非常基本的问题,但是我找不到任何东西。我不是要安装带有预样式化组件的整个库,只是为了能够在React应用程序的<select>中选择多个选项。

这里有一些我尝试过的onChange函数:

type Setter = React.Dispatch<React.SetStateAction<string[] | undefined>>
type SelectChange = React.ChangeEvent<HTMLSelectElement>

export const handleMultiSelectChange = <S extends Function = Setter>(
  value: string[] | undefined, setter: S
) => (
    e: SelectChange
  ): void => {
    const v = e.currentTarget.value
    if (value && value.length > 0) {
      const index = value.indexOf(v)
      if (index >= 0) {
        const newValue = value.filter((opt) => opt !== v)
        setter(newValue)
      } else {
        setter([...value, v])
      }
    } else {
      setter([v])
    }
  }
type Setter = React.Dispatch<React.SetStateAction<string[] | undefined>>
type SelectChange = React.ChangeEvent<HTMLSelectElement>

export const handleChangeMultiple = <S extends Function = Setter>(
  value: string[] | undefined = [], setter: S
) => (
    event: SelectChange
  ): void => {
    const {options} = event.currentTarget
    for (let i = 0, l = options.length; i < l; i += 1) {
      const option = options[i]
      if (option.selected) {
        alert(value.includes(option.value))
        if (value.includes(option.value)) {
          const index = value.indexOf(option.value)
          value.splice(index, 1)
        } else {
          value.push(option.value)
        }
      }
    }
    setter(value)
  }

(那些人的用法是这样的:)

const ExampleSelect = () => {
  const [value, setValue] = React.useState()
  return (
    <select
      multiple
      value={value}
      onChange={handleChangeMultiple(value, setValue)}
    >
      <option value='foo'>Foo</option>
      <option value='bar'>Bar</option>
      <option value='baz'>Baz</option>
    </select>
  )
}

(尽管这对我来说无法正常工作)

reactjs select jsx dropdown controlled-component
1个回答
1
投票

对于选择,e.target给您options数组,您可以遍历它的get selected选项。使用map获取实际值并将其存储在您的状态中。

© www.soinside.com 2019 - 2024. All rights reserved.