【问题标题】:React <select> automatic change does not trigger onChangeReact <select> 自动更改不会触发 onChange
【发布时间】:2021-12-06 03:47:50
【问题描述】:

在我的页面中,我有两个 &lt;select&gt; 元素,其中第二个的选项取决于第一个的值。

在这种情况下,“问题”是第一个选择中某个值的选项与第一个选择具有另一个值时给出的选项不同。基本上:

  • 阿尔法罗密欧
    • 朱丽叶塔
    • 水户
  • 保时捷
    • 卡宴
    • 911

我创建了一个简单的小提琴,只是为了向您展示示例和问题:https://codesandbox.io/s/select-autochange-7bfj6

请打开控制台看看我在说什么。所以,基本上,在开始时'Porsche''911' 被选中。然后,如果我将 '911' 更改为 'Cayenne' 一切都很好。

问题是当我将'Porsche' 更改为'Alfa' 时:应该如此,第二次选择将其值更改为'Giulietta',但是第二次选择的onChange 事件未触发。
我很确定问题出在 UI 和状态之间的某种去同步:在状态中,secondselect 仍然具有值'911',但由于该选项在第二次选择中不再可用,它会自动选择第一个可能的值。但自动选择只是“图形化的”。

我知道这可以通过在第二个选择中添加一个“null”值来解决,选项&lt;option value={''} label={'Select a Model'} /&gt;。但是我想在第一个选择发生变化时保持自动选择。

编辑:实际上,我提出的修复不是真正的修复:“选择模型”选项的值是 '',但仍然没有触发 handleSelectSelectChange,因此,虽然 UI 选择的值是 @ 987654335@,状态我还有'911'

【问题讨论】:

    标签: javascript reactjs typescript use-effect react-usememo


    【解决方案1】:
     React.useEffect(()=> {
        if (!secondOptionsMemoized.some(x=> x === secondSelectValue)) {
          console.log('Second Select Change in useEffect');
          setSecondSelectValue(secondOptionsMemoized[0]);
        }
     }, [secondSelectValue, secondOptionsMemoized]);
    

    【讨论】:

    • 谢谢!我想过这个问题,我相信它会奏效。不过,我想知道它是否存在保持选定值和 UI 选定值之间同步的解决方案。我的意思是,如果明天我有一个类似的案例,我需要写一个类似的 useEffect 来解决这个问题。
    【解决方案2】:

    您可以使用useEffect 代替useMemo 和另一个设置第二个选项的state

    import React, { useEffect } from "react";
    import "./styles.css";
    
    export default function App() {
      const alfaForSecondOptions = ["Giulietta", "Mito"];
      const otherForSecondOptions = ["Cayenne", "911"];
    
      const [firstSelectValue, setFirstSelectValue] = React.useState("Porsche");
      const [secondSelectValue, setSecondSelectValue] = React.useState("911");
      const [secondOptions, setSecondOptions] = React.useState(
        otherForSecondOptions
      );
    
      useEffect(() => {
        console.log(secondSelectValue);
      }, [secondOptions]);
    
      useEffect(() => {
        if (firstSelectValue === "Alfa") {
          setSecondOptions(alfaForSecondOptions);
          setSecondSelectValue("Giulietta");
        } else {
          setSecondOptions(otherForSecondOptions);
          setSecondSelectValue("911");
        }
      }, [firstSelectValue]);
    
      const handleFirstSelectChange = (e) => {
        console.log("First Select Change", e.target.value);
        setFirstSelectValue(e.target.value);
      };
    
      const handleSecondSelectChange = (e) => {
        console.log("Second Select Change", e.target.value);
        setSecondSelectValue(e.target.value);
      };
    
      return (
        <div className="App">
          <label>
            <p>Brand</p>
            <select onChange={handleFirstSelectChange} value={firstSelectValue}>
              <option value={"Alfa"} label={"Alfa"} />
              <option value={"Porsche"} label={"Porsche"} />
            </select>
          </label>
    
          <label>
            <p>Model</p>
            <select onChange={handleSecondSelectChange} value={secondSelectValue}>
              {secondOptions.map((x) => {
                return <option key={x} value={x} label={x} />;
              })}
            </select>
          </label>
        </div>
      );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-24
      • 2019-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-08
      • 2022-11-24
      相关资源
      最近更新 更多