将表单选择中的多个属性设置为状态

Posted

技术标签:

【中文标题】将表单选择中的多个属性设置为状态【英文标题】:Set multiple properties from a form selection to state 【发布时间】:2020-12-20 19:28:06 【问题描述】:

????代码重复????

所以我试图拥有一个初始状态对象,例如:prop1: val1, prop2: val2 并从两个 <selection> 字段中获取单独的值。 我在提交每个 event.target.value 时遇到问题。 我想出的唯一解决方案是将原始状态拆分为不同的对象,复制处理函数并在提交时合并它们。但正如你所看到的,这很快就变得丑陋了,我确信这可以优化,但我无法使用独特的事件处理程序。

const [firstSelection, setFirstSelection] = useState(color: 'green')
const [secondSelection, setSecondSelection] = useState(time: 'evening')

const handleFirstChange = e => setFirstSelection( color: e.target.value )
const handleSecondChange = e => setSecondSelection( time: e.target.value )

const getSelection = e => 
    e.preventDefault()
    console.log(...firstSelection, ...secondSelection)


const Form = () => 
    return (
        <form>
            <div className='selectWrapper'>
                <select name='color' value=firstSelection.color onChange=handleFirstChange>
                    <option value='red'>Red</option>
                    <option value='blue'>Blue</option>
                    <option value='yellow'>Yellow</option>
                    <option value='green'>Green</option>
                </select>
            </div>
            <div className='selectWrapper'>
                <select name='time' value=secondSelection.time onChange=handleSecondChange>
                    <option value='morning'>Morning</option>
                    <option value='evening'>Evening</option>
                    <option value='night'>Night</option>
                </select>
            </div>
            <input type='submit' value='Submit' onClick=getSelection/>
        </form>
    )

【问题讨论】:

【参考方案1】:

试试这个:

export default function Form() 
  const [selection, setSelection] = useState( color: "red", time: "morning" );

  const handleChange = (e) => 
    setSelection( ...selection, [e.target.name]: e.target.value );
  ;

  const getSelection = (e) => 
    e.preventDefault();
    console.log(selection);
  ;

  return (
    <form>
      <div className="selectWrapper">
        <select
          name="color"
          value=selection.color
          onChange=(e) => handleChange(e)
        >
          <option value="red">Red</option>
          <option value="blue">Blue</option>
          <option value="yellow">Yellow</option>
          <option value="green">Green</option>
        </select>
      </div>
      <div className="selectWrapper">
        <select
          name="time"
          value=selection.time
          onChange=(e) => handleChange(e)
        >
          <option value="morning">Morning</option>
          <option value="evening">Evening</option>
          <option value="night">Night</option>
        </select>
      </div>
      <input type="submit" value="Submit" onClick=getSelection />
    </form>
  );


【讨论】:

谢谢,我不知道“[e.target.name]: e.target.value” - 这解决了问题【参考方案2】:

您可以尝试只创建一个函数来更新状态,该函数使用&lt;select&gt;s 标签的names 作为状态对象的键。并将所有数据集中到一个状态。我将这个单一状态称为formState

const [formState, setFormState] = useState(color: 'green', time: 'evening')

const handleInput = e => setFormState(
  ...formState, 
  [e.target.name]: e.target.value  
)

const getSelection = e => 
    e.preventDefault()
    console.log(formState)


const Form = () => 
    return (
        <form>
            <div className='selectWrapper'>
                <select name='color' value=firstSelection.color onChange=handleInput>
                    <option value='red'>Red</option>
                    <option value='blue'>Blue</option>
                    <option value='yellow'>Yellow</option>
                    <option value='green'>Green</option>
                </select>
            </div>
            <div className='selectWrapper'>
                <select name='time' value=secondSelection.time onChange=handleInput>
                    <option value='morning'>Morning</option>
                    <option value='evening'>Evening</option>
                    <option value='night'>Night</option>
                </select>
            </div>
            <input type='submit' value='Submit' onClick=getSelection/>
        </form>
    )

【讨论】:

【参考方案3】:

您可以为选择创建一个可重用的组件,并使用对象作为选择值,通过输入名称检索

const CustomSelect = ( name, options, value, onChange ) => 
  return (
    <div className="selectWrapper">
      <select name=name value=value onChange=onChange>
        options.map((option) => (
          <option value=option.value>option.label</option>
        ))
      </select>
    </div>
  );
;

export default function Form() 
  const selectData = [
    
      name: "color",
      options: [
         label: "Red", value: "red" ,
         label: "Blue", value: "blue" ,
         label: "Yellow", value: "yellow" ,
         label: "Green", value: "green" 
      ]
    ,
    
      name: "time",
      options: [
         label: "Morning", value: "morning" ,
         label: "Evening", value: "evening" ,
         label: "Night", value: "night" 
      ]
    
  ];
  const [selection, setSelection] = useState(
    color: "green",
    time: "evening"
  );

  const getSelection = (e) => 
    e.preventDefault();
    console.log(selection);
  ;

  return (
    <div className="App">
      <form>
        selectData.map((sd) => (
          <CustomSelect
            name=sd.name
            options=sd.options
            value=selection[sd.name]
            onChange=(event) =>
              setSelection(
                ...selection,
                [event.target.name]: event.target.value
              )
            
          />
        ))
        <input type="submit" value="Submit" onClick=getSelection />
      </form>
    </div>
  );

Codesandbox 演示

【讨论】:

有趣的解决方案,我会尝试这个并希望了解这个额外组件创建的概念!

以上是关于将表单选择中的多个属性设置为状态的主要内容,如果未能解决你的问题,请参考以下文章

使用材料 ui 键盘日期选择器动态设置日期

选择多个用数组中的每个值替换一个单词

如何使用jquery重置表单中的多个选择框?

选择单选按钮后将复选框设置为选中状态

为一个属性使用多个输入字段

将选择多个表单中的值添加到 mysql