未知数量的输入的受控值?React 钩子形式

Controlled value on unknown quantity of inputs? React hook forms

提问人:Miguel V 提问时间:11/11/2023 更新时间:11/11/2023 访问量:18

问:

我有一个用户权限表,我希望能够通过 React Hook Forms 的控制器进行管理,该表本身如下所示:

User permissions table

(现在,权限是随机生成的,因此值很奇怪)

这些权限是通过 API 后端服务动态添加的,这意味着它们不是静态的,一些超级用户可以为“主题 A”生成权限表,例如,使用自己的原子权限,它会动态添加在上面显示的屏幕上。

我的问题是,当我更改某些复选框值时,会弹出错误“组件正在更改要控制的 SwitchBase 的不受控制的检查状态”,我想这是因为我没有从我的复选框中定义 defaultValues,但我不能这样做,因为我无法知道将来会有多少个 Subjects-Permissions。有没有办法解决这个问题?或者,我的方法错了吗?

我有以下代码:

我的整个表单,我把它放在一个只呈现对话框模式的自定义组件上。

import { Box } from '@mui/material'
import React, { useEffect, useState } from 'react'
import { FormProps } from './FormPassword'
import PermissionBox from './PermissionBox'
import { getPermisos } from '@/services/usuarios'
import { useForm } from 'react-hook-form'

const FormPermissions = (props: FormProps) => {
    const { idUser } = props;
    const [permisos, setPermisos] = useState([]);

    useEffect(() => {
        getPermisos(idUser).then(res => {
            setPermisos(res.data);
        })
    }, []);

    const methods = useForm();

    const { control, handleSubmit } = methods;

    const changePermissions = (data: any) => {
        ///TODO change permissions
        console.log(data);
    }

    return (
        <Box
            component='form'
            id={props.id}
            sx={{
                display: 'flex',
                flexDirection: 'row',
                flexWrap: 'wrap',
                justifyContent: 'space-around',
                gap: '1rem',
                p: '10px',
                alignItems: 'center'
            }}
            onSubmit={handleSubmit(changePermissions)}
        >
            {
                permisos && permisos.map((permiso: any, idx: number) => (
                    <PermissionBox key={idx} permiso={permiso} idUser={idUser} control={control} />
                ))
            }
        </Box>
    )
}

export default FormPermissions  

每个 Subject 的单个组件及其权限,用于呈现 N 个具有相应权限的表

const PermissionBox = (props: PermissionBoxProps) => {

    const { permiso } = props;

    const [manage, ...actions] = permiso.actions.toReversed();

    return (
        <Grid
            item
            xs={2}
            sx={{
                display: 'flex',
                flexDirection: 'column',
                border: 1,
                p: 1,
            }}
        >
            <Typography variant='h6'>
                {permiso.subject}
            </Typography>
            <Divider sx={{
                margin: '0px -10px 0px -10px',
                borderBottomWidth: 2
            }}
            />

            {
                manage && (
                    <FormGroup>
                        <FormControlLabel
                            label={traduceAction(manage.action)}
                            control={
                                <Checkbox
                                    checked={manage.checked}
                                    indeterminate={isIndeterminated(actions, manage)}
                                />
                            }
                        />
                    </FormGroup>
                )
            }

            {
                actions && actions.map((action, index) => {
                    return (
                        <FormGroup key={index} sx={{
                            ...(action.action != 'manage' && { ml: 2 }),
                        }}>
                            <Controller
                                name={`permisos.${props.idUser}.${permiso.subject}.${action.id}`}
                                control={props.control}
                                render={({ field: { onChange, value } }) => (
                                    <FormControlLabel
                                        label={traduceAction(action.action)}
                                        control={
                                            <Checkbox
                                                checked={value}
                                                onChange={onChange}
                                                indeterminate={isIndeterminated(actions, manage)}
                                            />
                                        }
                                    />
                                )}
                            />
                        </FormGroup>
                    )
                })
            }
        </Grid>
    )
};
reactjs typescript next.js 复选框 react-hook-form

评论


答: 暂无答案