目前,我正在实现用户编辑/创建表单。我将用户的所有信息保持在一种状态,这样我就可以将其发送到后端。
我的代码如下:
const UserEditPage = () => {
const [user, setUser] = useState();
const [roles, setRoles] = useState([]);
}
const roleOnChange = (event, value) => {
if (user.roles.find(role => role === value)) {
setUser({ ...user, roles: user.roles.filter(role => role !== value) });
} else {
setUser({ ...user, roles: [...user.roles, value] });
}
}
useEffect(() => {
getRoles().then(res => {
setRoles(res.data);
}
}, []);
return (
<div>
{roles.map(role => {
<input type="checkbox" onChange={event => roleOnChange(event, role.id)}
checked={user.roles.find(userRole => userRole === role.id)} />
})}
</div>
)
问题在于,当我单击复选框时,它们通常不会被选中或未选中。
我认为问题是以前的setUser函数没有完全完成,并且看不到新值。我该怎么做才能解决此问题?
答案 0 :(得分:1)
是的,无论如何,如果您有一组值并且需要在其中搜索一些值-最好使用一些索引对象而不是数组。例如集合。代码将是
const UserEditPage = () => {
const [user, setUser] = useState();
const [roles, setRoles] = useState([]);
}
const roleOnChange = (event, value) => {
const action = user.roles.has(value) ? 'delete' : 'add'
user.roles[action](value)
setUser({ ...user, roles: new Set(user.roles) });
}
return (
<div>
{roles.map(role => {
<input type="checkbox" onChange={event => roleOnChange(event, role.id)}
checked={user.roles.has(role.id)} />
})}
</div>
)
即使在使用数组时,要了解它是否具有一定的价值,最好使用include方法,因为它比find方法更快,并且在这种情况下更有意义
user.roles.includes(value)
答案 1 :(得分:0)
我可以看到的一个问题是,在每个渲染上,您都会计算N次的checbox的checked
属性,其中N是用户数量。
这意味着如果您有5个角色和5个用户,则将在每个渲染上计算5 * 5倍于选中的属性。
您可以使用一个根据角色ID保存检查值的对象,并且每次检查更改时,您只能更改一次该对象的值。例如
const [checkedHolder, updateCheckedHolder] = useState({role1: false, role2: false})
...
<input {...otherProps} checked={checkedHolder[roleId])} onChange={updateCheckedRoles[roleId]} />
和使用更改器功能:
我相信这将大大提高您的性能,因为您不必在每个渲染器上重复角色。