简体   繁体   English

Select 值在使用 setSate React 时第一次触发 onChange 事件时没有改变

[英]Select value doesnt change the first time I trigger onChange event when using setSate React

I have a set of select menus and I am trying to change a value when I select an option using onChange={updateValue} event.我有一组 select 菜单,当我 select 使用 onChange={updateValue} 事件的选项时,我试图更改一个值。 When I first select an option, the value is not being updated in the select menu.当我第一次使用 select 选项时,select 菜单中的值没有更新。 It only changes the second time I try to choose an option.它只会在我第二次尝试选择一个选项时发生变化。 Not sure what I am doing wrong.不知道我做错了什么。

Edit: I did some more research ( OnChange event using React JS for drop down ) and I believe I need the value of the select to be updated as well, using setState.编辑:我做了更多的研究( OnChange 事件使用 React JS 进行下拉),我相信我需要使用 setState 更新 select 的值。 I cant figure out how to do it without having a variable for each value and set the state again.如果没有每个值的变量并再次设置 state,我无法弄清楚如何做到这一点。

let selectMenus = [
  {
    id: 'id1',
    name: 'name1',
    label: 'label1',
    value: '0',
    options: [
      {
        text: 'All ages',
        value: '0',
      },
      {
        text: '35 - 37 yrs',
        value: '1',
      },
    ],
    buttonLabel: 'Refresh',
  },
  {
    id: 'id2',
    name: 'name2',
    label: 'label2',
    value: '1',
    options: [
      {
        text: 'All ages',
        value: '0',
      },
      {
        text: '45 - 50 yrs',
        value: '1',
      },
    ],
    buttonLabel: 'Refresh',
  },
];

const [url, setUrl] = useState('http://localhost:5000/selectDropdowns1');

const updateValue = () => {
  setUrl('http://localhost:5000/selectDropdowns2');
};

<form>
  {selectMenus.map((select) => (
    <div key={select.id} className='select-container'>
      <label htmlFor={select.id}>{select.label}</label>
      <select id={select.id} name={select.name} value={select.value} onChange={updateValue}>
        {select.options.map((option) => (
          <option value={option.value} key={uuid()}>
            {option.text}
          </option>
        ))}
      </select>
      <button>{select.buttonLabel}</button>
    </div>
  ))}
</form>;

The problem is that when you provide onChange prop to select component it become a controlled component .问题是,当您向 select 组件提供onChange道具时,它会成为受控组件

For more information: React Docs - Forms #controlled components更多信息: React Docs - Forms #受控组件

When you dealing with controlled components you must provide a value to it and when onChange triggerd it should update that value to work properly.当您处理受控组件时,您必须为其提供一个值,并且当 onChange 触发时,它应该更新该值以正常工作。 Since you did not provide the full code, I imagine you have an array of select menus and options attached to it.由于您没有提供完整的代码,我想您有一组 select 菜单和附加的选项。

So in this case every select component should have own onChange method and own value to work properly.所以在这种情况下,每个 select 组件都应该有自己的 onChange 方法和自己的值才能正常工作。 To achive this we should create another component for only Select Options.为了实现这一点,我们应该为仅 Select 选项创建另一个组件。 Like this;像这样;

function SelectComponent({ optionList, onSelected }) {
  const [value, setValue] = useState();

  const updateValue = ({ target }) => {
    setValue(target.value);
    if (onSelected) onSelected(target.value);
  };

  return (
    <>
      <label htmlFor={optionList.id}>{optionList.label}</label>
      <select
        id={optionList.id}
        name={optionList.name}
        value={value}
        onChange={updateValue}
      >
        {optionList.options.map((option) => (
          <option value={option.value} key={uuid()}>
            {option.text}
          </option>
        ))}
      </select>
      <button>{optionList.buttonLabel}</button>
    </>
  );
}

This component accepts to props;该组件接受道具; optionList and onSelected optionListonSelected

optionList is the list of options to render optionList是要渲染的选项列表

onSelected is a method that we call when user select and option onSelected是我们在用户 select 和选项时调用的方法

On main component, we should change the select section with our select component with props optionList and onSelected在主要组件上,我们应该使用带有道具optionListonSelected的 select 组件更改 select 部分

  return (
    <div>
      {selectMenus.map((select) => (
        <div key={select.id} className="select-container">
          <SelectComponent optionList={select} onSelected={updateValue} />
        </div>
      ))}
    </div>
  );

So overall code is like this:所以整体代码是这样的:

import { useState } from "react";
import { v4 as uuid } from "uuid";

export default function App() {
  const [url, setUrl] = useState();

  const updateValue = (value) => {
    setUrl(value);
  };

  const selectMenus = [
    {
      id: 1,
      label: "Menu 1",
      name: "menu1",
      buttonLabel: "Menu 1",
      options: [
        {
          text: "option 1",
          value: "option1"
        },
        {
          text: "option 2",
          value: "option2"
        },
        {
          text: "option 3",
          value: "option3"
        }
      ]
    },
    {
      id: 2,
      label: "Menu 2",
      name: "menu2",
      buttonLabel: "Menu 2",
      options: [
        {
          text: "option 1",
          value: "option1"
        },
        {
          text: "option 2",
          value: "option2"
        },
        {
          text: "option 3",
          value: "option3"
        }
      ]
    },
    {
      id: 3,
      label: "Menu 3",
      name: "menu3",
      buttonLabel: "Menu 3",
      options: [
        {
          text: "option 1",
          value: "option1"
        },
        {
          text: "option 2",
          value: "option2"
        },
        {
          text: "option 3",
          value: "option3"
        }
      ]
    }
  ];

  return (
    <div className="App">
      <h1>URL Value: {url}</h1>
      {selectMenus.map((select) => (
        <div key={select.id} className="select-container">
          <SelectComponent optionList={select} onSelected={updateValue} />
        </div>
      ))}
    </div>
  );
}

function SelectComponent({ optionList, onSelected }) {
  const [value, setValue] = useState();

  const updateValue = ({ target }) => {
    setValue(target.value);
    if (onSelected) onSelected(target.value);
  };

  return (
    <>
      <label htmlFor={optionList.id}>{optionList.label}</label>
      <select
        id={optionList.id}
        name={optionList.name}
        value={value}
        onChange={updateValue}
      >
        {optionList.options.map((option) => (
          <option value={option.value} key={uuid()}>
            {option.text}
          </option>
        ))}
      </select>
      <button>{optionList.buttonLabel}</button>
    </>
  );
}

Working example is overhere codesandbox工作示例在这里代码和框

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 选择值在我第一次触发 onChange 事件时不会改变 - Select value doesn't change the first time I trigger onChange event 反应选择onChange不使用选项值 - React select onChange doesnt use the options value 仅通过单击即可在反应选择触发器上进行onchange事件 - onchange event on react select trigger only by clicking 反应<select>自动更改不会触发 onChange - React <select> automatic change does not trigger onChange select2 &#39;change&#39; 事件不会第一次触发 - select2 'change' event doesn't trigger for the first time Select onchange事件在第一次不起作用 - Select onchange event does not works on first time 触发反应选择 onchange - Trigger react select onchange react-select-event 不会触发 onChange function 在测试期间设置值 - react-select-event doesn't trigger the onChange function to set the value during testing 在 React 中重新渲染 select 元素后触发 onChange 事件 - Trigger an onChange event after a select element is re-rendered in React 当使用 PHP 保存下拉菜单选择时,它会记住选择但不会触发 onchange 事件,在重新加载时更改 CSS - When using PHP to save a drop down menu selection it remembers the selection but doesnt trigger the onchange event changing the CSS when reloaded
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM