React+Inertia项目中如何根据数组值设置复选框默认选中并解决无法取消问题
问题分析与修复方案
你的代码里有几个关键问题导致复选框状态异常,逐一解决就能搞定:
1. 权限数组初始化错误
直接修改data.permissions(data.permissions.push(...))不符合Inertia useForm的使用规范,而且没有在组件挂载时正确初始化,应该用useEffect结合setData来设置初始选中的权限:
useEffect(() => { // 从role.permissions中提取权限名数组 const initialPermissions = role.permissions.map(p => p.name); setData('permissions', initialPermissions); }, [role, setData]);
删掉原来的mapPermissionsOnRole函数,改用上面的useEffect,确保组件挂载时就正确初始化选中状态。
2. 复选框状态判断逻辑颠倒
原来的checked={props.permissions[i].name.includes(data.permissions)}逻辑完全反了,应该判断当前权限名是否在选中数组里,正确写法是:
checked={data.permissions.includes(permission.name)}
另外你遍历的是role.permissions,这会导致只显示角色已有的权限,应该遍历所有可用权限props.permissions,这样才能展示全部权限选项供用户选择。
3. 取消选中时的字段名拼写错误
handleChecked里取消选中时写了permissionss(多了个s),导致更新的是不存在的字段,data.permissions根本没变化,所以复选框无法取消选中:
// 错误写法 setData("permissionss", ...) // 正确写法 setData("permissions", ...)
4. 提交时的ID错误
put(route('role.update',permission.id))里的permission.id应该是role.id,因为你是更新当前角色的权限。
修复后的完整代码
import { useEffect } from 'react'; import { usePage, useForm } from '@inertiajs/react'; import AuthenticatedLayout from './AuthenticatedLayout'; import Checkbox from './Checkbox'; import PrimaryButton from './PrimaryButton'; export default function EditPermission(props) { const { role } = usePage().props; const { data, setData, put, processing, errors, reset } = useForm({ name: role.name || '', permissions: [], }); // 初始化角色已有的权限 useEffect(() => { const initialPermissions = role.permissions.map(p => p.name); setData('permissions', initialPermissions); }, [role, setData]); const handleChecked = (e) => { const value = e.target.name; if (e.target.checked) { // 避免重复添加 if (!data.permissions.includes(value)) { setData("permissions", [...data.permissions, value]); } } else { setData( "permissions", data.permissions.filter(item => item !== value) ); } }; const submit = (e) => { e.preventDefault(); put(route('role.update', role.id)); }; return ( <AuthenticatedLayout auth={props.auth} errors={props.errors}> <div className="w-full lg:max-w-6xl mt-6 px-6 py-4 bg-white shadow-md overflow-hidden sm:rounded-lg"> <form onSubmit={submit}> <div> {props.permissions && props.permissions.length > 0 ? ( props.permissions.map((permission) => ( <div key={permission.name}> <Checkbox checked={data.permissions.includes(permission.name)} name={permission.name} handleChange={handleChecked} /> {permission.name} </div> )) ) : ( <p>Permissions Coming Soon!</p> )} <PrimaryButton className="ml-4" processing={processing}> Update </PrimaryButton> </div> </form> </div> </AuthenticatedLayout> ); }
额外优化点:
- 给
map的元素加上key={permission.name},避免React警告 - 添加重复判断
if (!data.permissions.includes(value)),防止重复添加相同权限
内容的提问来源于stack exchange,提问作者shinichirou ikebe
相关产品推荐
相关产品推荐

