React useState中的数组:性能问题

时间:2020-09-19 10:23:39

标签: javascript reactjs

目前,我正在实现用户编辑/创建表单。我将用户的所有信息保持在一种状态,这样我就可以将其发送到后端。

我的代码如下:

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函数没有完全完成,并且看不到新值。我该怎么做才能解决此问题?

2 个答案:

答案 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]} />

和使用更改器功能:

我相信这将大大提高您的性能,因为您不必在每个渲染器上重复角色。