在 React 中设置单选按钮值 [英] Set radio button value in React

查看:18
本文介绍了在 React 中设置单选按钮值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个带有单选按钮的简单反应应用程序.

这里有一个可用的默认数据,例如,

const defaultData = [{ ContactMode: 3 }, { ContactMode: 2 }, { ContactMode: 2 }];

要求:

->需要迭代这个 defaultData 并在每一行中指定它们各自的 ContactMode 模式.

工作片段:

const { useState } = React;const App = () =>;{const [formValue, setFormValue] = useState({联系方式:1});const defaultData = [{ ContactMode: 3 }, { ContactMode: 2 }, { ContactMode: 2 }];const handleInputChange = (e, index) =>{常量 { 名称,值 } = event.target;设置表单值({...表单值,[名称]:值});};const submitData = () =>{控制台.log(formValue);};返回 (

<表格>{defaultData.map((item, index) => {return (<React.Fragment><标签>联系方式</label><输入类型="收音机"名称="联系方式"检查={item.ContactMode == 1}值={1}onChange={(事件) =>处理输入变化(索引,事件)}/>{" "}电子邮件<输入类型="收音机"名称="联系方式"检查={item.ContactMode == 2}值={2}onChange={(事件) =>处理输入变化(索引,事件)}/>{" "}文本<输入类型="收音机"名称="联系方式"检查={item.ContactMode == 3}值={3}onChange={(事件) =>处理输入变化(索引,事件)}/>{" "}两个都<br/><br/><按钮类型="按钮">保存</按钮><br/><br/><br/></React.Fragment>);})}</表格></div>);};ReactDOM.render(<App/>, document.getElementById("root"));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.11.0/umd/react.production.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script><div id="root"></div>

预期输出:

联系方式电子邮件文本两者(选中)联系方式电子邮件文本(选中)两者联系方式电子邮件文本(选中)两者

注意:我无法修改名称属性 name=ContactMode".. 原因是我每行都有单独的保存按钮,点击该按钮特定行将被保存的保存按钮.每一行都应该有 name="ContactMode" ..

由于我的问题不清楚我想要实现的目标,我将在此处提供整个代码.

-> 我有一个步进表单,其中第 2 步是就业部分,默认情况下我有要设置到表单中的值,

const dynamicData = [{就业ID:1,companyName: '公司一',名称:指定一",联系方式:3,},{就业ID:2,companyName: '公司二',名称:指定一",联系方式:2,},];

->useEffecthook 里面我设置了像这样的表单值,

 React.useEffect(() => {设置扩展(0);setValue((上一个) => {const companyDetails = [...dynamicData];返回 { ...prev, companyDetails };});}, []);

这里带有输入框的表单值被正确绑定,但是单选按钮的值没有被检查.

-> 有两个数据可用,但默认情况下第一个将展开,而第二个将在单击下方的 Expand 按钮时打开第一个.

-> 点击 save 按钮后,该特定对象 (inputField) 将与修改数据..

这里的 ISSUE 是,如果我们修改数据,那么一切正常,但单单 radio checked 属性并没有使项目检查..(检查指示不起作用)..

请转到下面给出的代码框中的第 2 步以查看问题.要查看第二项,请单击展开按钮..

请帮我在每一行设置默认单选按钮值.

解决方案

在你的沙箱中,我能够让单选按钮工作

  1. 为每个映射的无线电组提供唯一的名称
  2. 更新更改处理程序以唯一处理 ContactMode 属性.

更新无线电组以使用当前映射的索引,以使它们在所有映射的组中唯一.

handleInputChange中添加一个case来专门处理ContactMode.

const handleInputChange = (index, event) =>{常量 { 名称,值 } = event.target;if (name === 'designation' && !isLettersOnly(value)) {返回;}if (name.startsWith('ContactMode')) {//<-- 检查名称前缀setValue((上一个) => ({...上一页,companyDetails: prev.companyDetails.map((detail, i) =>我 === 索引?{...细节,ContactMode: Number(value),//<-- 存储在正确的键下,作为字符串相等检查的数字}: 细节,),}));返回;//<-- 提前返回,因此跳过其他状态更新!}setValue((上一个) => {const companyDetails = prev.companyDetails.map((v, i) => {如果(我!==索引){返回 v;}返回 { ...v, [名称]: 值 };});返回 { ...prev, companyDetails };});};

I am making a simple react app with form that has radio buttons.

Here there is a default data available like,

const defaultData = [{ ContactMode: 3 }, { ContactMode: 2 }, { ContactMode: 2 }];

Requirement:

-> Need to iterate this defaultData and assign their respective ContactMode mode as checked in each row.

Working Snippet:

const { useState } = React;

const App = () => {
  const [formValue, setFormValue] = useState({
    ContactMode: 1
  });

  const defaultData = [{ ContactMode: 3 }, { ContactMode: 2 }, { ContactMode: 2 }];

  const handleInputChange = (e, index) => {
    const { name, value } = event.target;
    setFormValue({
      ...formValue,
      [name]: value
    });
  };

  const submitData = () => {
    console.log(formValue);
  };

  return (
    <div>
      <form>
        {defaultData.map((item, index) => {
          return (<React.Fragment>
            <label> Contact Mode </label>
            <input
              type="radio"
              name="ContactMode"
              checked={item.ContactMode == 1}
              value={1}
              onChange={(event) => handleInputChange(index, event)}
            />{" "}
            Email
            <input
              type="radio"
              name="ContactMode"
              checked={item.ContactMode == 2}
              value={2}
              onChange={(event) => handleInputChange(index, event)}
            />{" "}
            Text
            <input
              type="radio"
              name="ContactMode"
              checked={item.ContactMode == 3}
              value={3}
              onChange={(event) => handleInputChange(index, event)}
            />{" "}
            Both
            <br />
            <br />
            <button type="button">
               Save
             </button>
            <br />
            <br />
            <br />
          </React.Fragment>);
        })}
      </form>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.11.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Expected output:

Contact Mode  Email Text Both (Checked)

Contact Mode  Email Text(Checked) Both

Contact Mode  Email Text(Checked) Both

Note: I can't modify the name attribute name="ContactMode".. Reason is I also have individual save button each row and on click of that save button that particular row will gets saved.. And each row should have name="ContactMode" ..

Edit:

As my question is not clear in what I am trying to achieve, I am going to give the entire code here.

-> I have a stepper form in which Step 2 is employment section and by default I have the values to set into the form,

const dynamicData = [
  {
    EmploymentID: 1,
    companyName: 'Company One',
    designation: 'Designation One',
    ContactMode: 3,
  },
  {
    EmploymentID: 2,
    companyName: 'Company two',
    designation: 'Designation One',
    ContactMode: 2,
  },
];

-> Inside useEffecthook I set the form value like,

  React.useEffect(() => {
    setExpanded(0);
    setValue((prev) => {
      const companyDetails = [...dynamicData];
      return { ...prev, companyDetails };
    });
  }, []);

Here the form values with input boxes are binded properly but the radio button value doesn't gets checked.

-> There are two data's available but the first one will be expanded by default and whereas the second one will gets opened on click of the Expand button below the first one.

-> On click of the save button, that particular object (inputField) will be console logged (testing only) along with modified data..

Here the ISSUE is if we modify the data then things are working fine but the radio checked attribute alone not making the item checked.. (Checked indication is not working)..

Please go to step 2 in the below given codesandbox to see the issue.. To see the second item, click on the expand button..

Please kindly help me to set default radio button value in each row.

解决方案

In your sandbox I was able to get the radio buttons to work by

  1. Providing a unique name for each mapped radio group
  2. Update the change handler to uniquely handle the ContactMode property.

Update the radio groups to use the current mapped index in order to make them unique among all mapped groups.

<div className="form-group col-sm-4">
  <label className="inline-flex items-center mr-6">
    <input
      type="radio"
      className="form-radio border-black"
      name={`ContactMode-${index}`} // <-- append index to name
      value={1}
      checked={inputField.ContactMode === 1} // <-- use strict "==="
      onChange={(event) => handleInputChange(index, event)}
    />
    <span className="ml-2">Email</span>
  </label>
</div>
<div className="form-group col-sm-4">
  <label className="inline-flex items-center mr-6">
    <input
      type="radio"
      className="form-radio border-black"
      name={`ContactMode-${index}`}
      value={2}
      checked={inputField.ContactMode === 2}
      onChange={(event) => handleInputChange(index, event)}
    />
    <span className="ml-2">Text</span>
  </label>
</div>
<div className="form-group col-sm-4">
  <label className="inline-flex items-center mr-6">
    <input
      type="radio"
      className="form-radio border-black"
      name={`ContactMode-${index}`}
      value={3}
      checked={inputField.ContactMode === 3}
      onChange={(event) => handleInputChange(index, event)}
    />
    <span className="ml-2">Both</span>
  </label>
</div>

In the handleInputChange add a case to handle ContactMode specially.

const handleInputChange = (index, event) => {
  const { name, value } = event.target;
  if (name === 'designation' && !isLettersOnly(value)) {
    return;
  }

  if (name.startsWith('ContactMode')) { // <-- check name prefix
    setValue((prev) => ({
      ...prev,
      companyDetails: prev.companyDetails.map((detail, i) =>
        i === index
          ? {
              ...detail,
              ContactMode: Number(value), // <-- store back under correct key, as number for string equality check
            }
          : detail,
      ),
    }));
    return; // <-- return early so other state update is skipped!
  }

  setValue((prev) => {
    const companyDetails = prev.companyDetails.map((v, i) => {
      if (i !== index) {
        return v;
      }

      return { ...v, [name]: value };
    });

    return { ...prev, companyDetails };
  });
};

这篇关于在 React 中设置单选按钮值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆