在 React 中设置单选按钮值
Set radio button value in React
我正在制作一个带有单选按钮的简单 React 应用程序。
这里有一个可用的默认数据,如
const defaultData = [{ ContactMode: 3 }, { ContactMode: 2 }, { ContactMode: 2 }];
要求:
-> 需要迭代此 defaultData
并在每一行中分配各自的 ContactMode
模式。
工作代码段:
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>
预期输出:
Contact Mode Email Text Both (Checked)
Contact Mode Email Text(Checked) Both
Contact Mode Email Text(Checked) Both
注意:我无法修改名称属性name="ContactMode"
..原因是我每行都有单独的保存按钮,点击那个保存按钮特定行将被保存..每行应该有 name="ContactMode"
..
编辑:
由于我的问题不清楚我要实现的目标,我将在此处提供完整的代码。
-> 我有一个步进表格,其中第 2 步是就业部分,默认情况下我有要设置到表格中的值,
const dynamicData = [
{
EmploymentID: 1,
companyName: 'Company One',
designation: 'Designation One',
ContactMode: 3,
},
{
EmploymentID: 2,
companyName: 'Company two',
designation: 'Designation One',
ContactMode: 2,
},
];
-> 在 useEffect
挂钩中,我将表单值设置为
React.useEffect(() => {
setExpanded(0);
setValue((prev) => {
const companyDetails = [...dynamicData];
return { ...prev, companyDetails };
});
}, []);
此处带有输入框的表单值已正确绑定,但未检查单选按钮值。
-> 有两个数据可用,但第一个数据将默认展开,而第二个数据将在单击下面的 Expand
按钮时打开第一个。
-> 单击 save
按钮时,该特定对象 (inputField
) 将与修改后的数据一起被控制台记录(仅测试) ..
这里的问题 是如果我们修改数据那么一切正常,但是单独的单选检查属性不能检查项目..(检查指示不工作)。 .
请转到下面给出的代码和框中的第 2 步查看问题。要查看第二项,请单击展开按钮。
请帮我设置每行的默认单选按钮值。
我认为这是因为所有的收音机都具有相同的名称属性
每个组都应该有不同的名称。
例如:
name = " ex1"
name = "ex2"
name = "ex3"
对于每个新组都应如此命名。
如果你使用相同的名字,一切都会变得一团糟
另一个认为你 ==
而不是 ===
item.ContactMode == 3
最好用===
@TalOrlanczyk 的回答是正确的。您总共打印了 9 个单选按钮,并且所有按钮的名称属性都具有相同的值。所以从技术上讲,这就像有一个带有 9 个单选按钮的单选按钮,这意味着一个单选按钮只能接受一个值。
我 运行 你的代码,它只在第 3 行选择了“文本”。
如果你想拥有 3 个单独的行(无线电组),你需要尝试这样的事情:
<input
type="radio"
name={"ContactMode"+index}
checked={item.ContactMode == 1}
value={1}
onChange={(event) => handleInputChange(index, event)}
/>{" "}
Email
<input
type="radio"
name={"ContactMode"+index}
checked={item.ContactMode == 2}
value={2}
onChange={(event) => handleInputChange(index, event)}
/>{" "}
Text
<input
type="radio"
name={"ContactMode"+index}
checked={item.ContactMode == 3}
value={3}
onChange={(event) => handleInputChange(index, event)}
/>{" "}
尝试并重新运行您的代码
您的代码中存在一些问题...
每次组件 returns 时,.map
都会在 defaultData
上调用。因此未映射到状态。
如果您希望每次迭代都使用相同的名称,则需要对每次迭代使用 <form>
否则所有单选按钮将组合在一起,因此仅显示最后一个单选按钮如标记。
最好用===
代替==
我修改了你的代码,defaultData
用于初始化状态
const { useState } = React;
const defaultData = [{ ContactMode: 3 }, { ContactMode: 2 }, { ContactMode: 2 }];
const App = () => {
const [formValue, setFormValue] = useState([...defaultData]);
const handleInputChange = (index, e) => {
const { name, value } = e.target;
const newFormValue = [...formValue];
newFormValue.splice(index,1,{[name]: value});
setFormValue(newFormValue);
};
const submitData = () => {
console.log(formValue);
};
return (
<div>
{formValue.map((item, index) => {
return (<form>
<label> Contact Mode </label>
<input
type="radio"
name="ContactMode"
checked={Number(item.ContactMode) === 1}
value={1}
onChange={(event) => handleInputChange(index, event)}
/>{" "}
Email
<input
type="radio"
name="ContactMode"
checked={Number(item.ContactMode) === 2}
value={2}
onChange={(event) => handleInputChange(index, event)}
/>{" "}
Text
<input
type="radio"
name="ContactMode"
checked={Number(item.ContactMode) === 3}
value={3}
onChange={(event) => handleInputChange(index, event)}
/>{" "}
Both
<br />
<br />
</form>);
})}
<button type="button" onClick={submitData}>
{" "}
Submit{" "}
</button>
</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
属性。
更新无线电组以使用当前映射索引,以便使它们在所有映射组中唯一。
<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>
在handleInputChange
中加个case专门处理ContactMode
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 应用程序。
这里有一个可用的默认数据,如
const defaultData = [{ ContactMode: 3 }, { ContactMode: 2 }, { ContactMode: 2 }];
要求:
-> 需要迭代此 defaultData
并在每一行中分配各自的 ContactMode
模式。
工作代码段:
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>
预期输出:
Contact Mode Email Text Both (Checked)
Contact Mode Email Text(Checked) Both
Contact Mode Email Text(Checked) Both
注意:我无法修改名称属性name="ContactMode"
..原因是我每行都有单独的保存按钮,点击那个保存按钮特定行将被保存..每行应该有 name="ContactMode"
..
编辑:
由于我的问题不清楚我要实现的目标,我将在此处提供完整的代码。
-> 我有一个步进表格,其中第 2 步是就业部分,默认情况下我有要设置到表格中的值,
const dynamicData = [
{
EmploymentID: 1,
companyName: 'Company One',
designation: 'Designation One',
ContactMode: 3,
},
{
EmploymentID: 2,
companyName: 'Company two',
designation: 'Designation One',
ContactMode: 2,
},
];
-> 在 useEffect
挂钩中,我将表单值设置为
React.useEffect(() => {
setExpanded(0);
setValue((prev) => {
const companyDetails = [...dynamicData];
return { ...prev, companyDetails };
});
}, []);
此处带有输入框的表单值已正确绑定,但未检查单选按钮值。
-> 有两个数据可用,但第一个数据将默认展开,而第二个数据将在单击下面的 Expand
按钮时打开第一个。
-> 单击 save
按钮时,该特定对象 (inputField
) 将与修改后的数据一起被控制台记录(仅测试) ..
这里的问题 是如果我们修改数据那么一切正常,但是单独的单选检查属性不能检查项目..(检查指示不工作)。 .
请转到下面给出的代码和框中的第 2 步查看问题。要查看第二项,请单击展开按钮。
请帮我设置每行的默认单选按钮值。
我认为这是因为所有的收音机都具有相同的名称属性 每个组都应该有不同的名称。 例如:
name = " ex1"
name = "ex2"
name = "ex3"
对于每个新组都应如此命名。
如果你使用相同的名字,一切都会变得一团糟
另一个认为你 ==
而不是 ===
item.ContactMode == 3
最好用===
@TalOrlanczyk 的回答是正确的。您总共打印了 9 个单选按钮,并且所有按钮的名称属性都具有相同的值。所以从技术上讲,这就像有一个带有 9 个单选按钮的单选按钮,这意味着一个单选按钮只能接受一个值。 我 运行 你的代码,它只在第 3 行选择了“文本”。
如果你想拥有 3 个单独的行(无线电组),你需要尝试这样的事情:
<input
type="radio"
name={"ContactMode"+index}
checked={item.ContactMode == 1}
value={1}
onChange={(event) => handleInputChange(index, event)}
/>{" "}
Email
<input
type="radio"
name={"ContactMode"+index}
checked={item.ContactMode == 2}
value={2}
onChange={(event) => handleInputChange(index, event)}
/>{" "}
Text
<input
type="radio"
name={"ContactMode"+index}
checked={item.ContactMode == 3}
value={3}
onChange={(event) => handleInputChange(index, event)}
/>{" "}
尝试并重新运行您的代码
您的代码中存在一些问题...
每次组件 returns 时,
.map
都会在defaultData
上调用。因此未映射到状态。如果您希望每次迭代都使用相同的名称,则需要对每次迭代使用
<form>
否则所有单选按钮将组合在一起,因此仅显示最后一个单选按钮如标记。最好用
===
代替==
我修改了你的代码,defaultData
用于初始化状态
const { useState } = React;
const defaultData = [{ ContactMode: 3 }, { ContactMode: 2 }, { ContactMode: 2 }];
const App = () => {
const [formValue, setFormValue] = useState([...defaultData]);
const handleInputChange = (index, e) => {
const { name, value } = e.target;
const newFormValue = [...formValue];
newFormValue.splice(index,1,{[name]: value});
setFormValue(newFormValue);
};
const submitData = () => {
console.log(formValue);
};
return (
<div>
{formValue.map((item, index) => {
return (<form>
<label> Contact Mode </label>
<input
type="radio"
name="ContactMode"
checked={Number(item.ContactMode) === 1}
value={1}
onChange={(event) => handleInputChange(index, event)}
/>{" "}
Email
<input
type="radio"
name="ContactMode"
checked={Number(item.ContactMode) === 2}
value={2}
onChange={(event) => handleInputChange(index, event)}
/>{" "}
Text
<input
type="radio"
name="ContactMode"
checked={Number(item.ContactMode) === 3}
value={3}
onChange={(event) => handleInputChange(index, event)}
/>{" "}
Both
<br />
<br />
</form>);
})}
<button type="button" onClick={submitData}>
{" "}
Submit{" "}
</button>
</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>
在你的沙盒中,我能够通过
让单选按钮工作- 为每个映射的无线电组 提供唯一的
- 更新更改处理程序以唯一处理
ContactMode
属性。
name
更新无线电组以使用当前映射索引,以便使它们在所有映射组中唯一。
<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>
在handleInputChange
中加个case专门处理ContactMode
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 };
});
};