在 React js 中使用选中的处理程序实现动态复选框
Implement dynamic checkbox with checked handler in React js
我在为数组的动态复选框设置状态时遇到问题,使用选中的处理程序将对象从 false 更改为 true。
下面是我的代码:
const [form, setForm] = useState({
tags:[
{ name: "Athletic/Higher caloric", isChecked: false },
{ name: "Aggressive Weight Loss", isChecked: false },
{ name: "Quick and Easy", isChecked: false } ]})
const onCheckedHandler = (index) => {
const updatedTags =
form.tags.map((tag, i) => {
if (index === i) {
form.tags[i].isChecked = !form.tags[i].isChecked;
}
return { tag };
});
setForm(updatedTags);
return (
{form.tags.map((tag, i) => (
<div>
<label>{tag.name}</label>
<input
type="checkbox"
checked={tag.isChecked}
onChange={(event) => onCheckedHandler(i)}
key={i} />
</div>
))})
我收到此错误:“未捕获类型错误:无法在创建时读取未定义(读取 'map')的属性(第 107 行)”
但是第 107 行只是另一个有效且完全不相关的地图函数的开始。我究竟做错了什么?我尝试避免使用 if 语句直接在对象中改变 isChecked 值。也许这就是我设置状态的方式?
问题可能出自这里:
return (
{form.tags.map((tag, i) => (
<div>
<label>{tag.name}</label>
<input
type="checkbox"
checked={tag.isChecked}
onChange={(event) => onCheckedHandler(i)}
key={i} />
</div>))}
)
问题是您正在尝试使用 form
状态进行渲染,该状态在(组件的)安装时可能是 undefined
。正如你的错误所说 cannot read property of undefined, reading map
它可能指的是 form.tags
未定义并且无法读取它的地图。
一个好主意是在渲染之前检查您尝试渲染的内容是否已定义。例如:
return (
{form.tags ? form.tags.map((tag, i) => (
<div>
<label>{tag.name}</label>
<input
type="checkbox"
checked={tag.isChecked}
onChange={(event) => onCheckedHandler(i)}
key={i} />
</div>)) : <div>Loading</div>}
)
据我了解:
- 初始状态是一个对象
const [form, setForm] = useState({...});
- 这有一个名为 tags 的道具。
- 但是,变量
updatedTags
(在handler-method中)是一个数组。这不是一个对象。
- 因此,setForm(updatedTags) 会将
form
设置为一个数组,其中不会有任何名为 tags
的属性
因此,请尝试像这样更改处理程序:
const onCheckedHandler = (index) => {
setForm(prev => ({
...prev,
tags: [
...prev?.tags?.map(
({isChecked, ...rest}, idx) => (
idx === index
? {...rest, isChecked: !isChecked}
: {...rest, isChecked}
)
)
]
}));
};
此外,请在 return
上尝试映射之前使用检查。可能会尝试这样的事情:
form?.tags?.map(...)
或
form && form.tags && Array.isArray(form.tags) && form.tags.map(...)
我在为数组的动态复选框设置状态时遇到问题,使用选中的处理程序将对象从 false 更改为 true。
下面是我的代码:
const [form, setForm] = useState({
tags:[
{ name: "Athletic/Higher caloric", isChecked: false },
{ name: "Aggressive Weight Loss", isChecked: false },
{ name: "Quick and Easy", isChecked: false } ]})
const onCheckedHandler = (index) => {
const updatedTags =
form.tags.map((tag, i) => {
if (index === i) {
form.tags[i].isChecked = !form.tags[i].isChecked;
}
return { tag };
});
setForm(updatedTags);
return (
{form.tags.map((tag, i) => (
<div>
<label>{tag.name}</label>
<input
type="checkbox"
checked={tag.isChecked}
onChange={(event) => onCheckedHandler(i)}
key={i} />
</div>
))})
我收到此错误:“未捕获类型错误:无法在创建时读取未定义(读取 'map')的属性(第 107 行)”
但是第 107 行只是另一个有效且完全不相关的地图函数的开始。我究竟做错了什么?我尝试避免使用 if 语句直接在对象中改变 isChecked 值。也许这就是我设置状态的方式?
问题可能出自这里:
return (
{form.tags.map((tag, i) => (
<div>
<label>{tag.name}</label>
<input
type="checkbox"
checked={tag.isChecked}
onChange={(event) => onCheckedHandler(i)}
key={i} />
</div>))}
)
问题是您正在尝试使用 form
状态进行渲染,该状态在(组件的)安装时可能是 undefined
。正如你的错误所说 cannot read property of undefined, reading map
它可能指的是 form.tags
未定义并且无法读取它的地图。
一个好主意是在渲染之前检查您尝试渲染的内容是否已定义。例如:
return (
{form.tags ? form.tags.map((tag, i) => (
<div>
<label>{tag.name}</label>
<input
type="checkbox"
checked={tag.isChecked}
onChange={(event) => onCheckedHandler(i)}
key={i} />
</div>)) : <div>Loading</div>}
)
据我了解:
- 初始状态是一个对象
const [form, setForm] = useState({...});
- 这有一个名为 tags 的道具。
- 但是,变量
updatedTags
(在handler-method中)是一个数组。这不是一个对象。 - 因此,setForm(updatedTags) 会将
form
设置为一个数组,其中不会有任何名为tags
的属性
因此,请尝试像这样更改处理程序:
const onCheckedHandler = (index) => {
setForm(prev => ({
...prev,
tags: [
...prev?.tags?.map(
({isChecked, ...rest}, idx) => (
idx === index
? {...rest, isChecked: !isChecked}
: {...rest, isChecked}
)
)
]
}));
};
此外,请在 return
上尝试映射之前使用检查。可能会尝试这样的事情:
form?.tags?.map(...)
或
form && form.tags && Array.isArray(form.tags) && form.tags.map(...)