You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何通过react-hook-form传递API默认值给TableRole组件

解决方案

一、父组件:获取API数据并初始化react-hook-form

先通过GraphQL拉取权限数据,再把数据转换成react-hook-form需要的结构,作为表单默认值初始化,最后把表单实例和原始数据传给子组件。

import { useQuery } from '@apollo/client';
import { useForm, useEffect } from 'react-hook-form';
import TableRole from './TableRole';

// 你的GraphQL查询语句
const GET_ROLE_PERMISSIONS = gql`
  query GetRolePermissions {
    roles {
      id
      name
      permissions {
        id
        permissionKey
        isEnabled
      }
    }
  }
`;

const RolePermissionManager = () => {
  const { data, loading } = useQuery(GET_ROLE_PERMISSIONS);
  const { register, control, reset } = useForm({
    defaultValues: {},
    shouldUnregister: false
  });

  // 数据加载完成后重置表单默认值
  useEffect(() => {
    if (!data?.roles) return;
    
    const formDefaultValues = data.roles.reduce((acc, role) => {
      role.permissions.forEach(perm => {
        // 用「角色ID-权限key」作为唯一字段名,避免冲突
        acc[`role_${role.id}_perm_${perm.permissionKey}`] = perm.isEnabled;
      });
      return acc;
    }, {});
    
    reset(formDefaultValues);
  }, [data, reset]);

  if (loading) return <div>加载权限数据中...</div>;

  return (
    <TableRole
      roles={data.roles}
      register={register}
      control={control}
    />
  );
};

二、子组件TableRole:渲染表格与Switch组件

接收父组件传过来的角色数据和表单实例,遍历生成表格,为每个Switch绑定对应的表单字段,react-hook-form会自动读取默认值渲染。

import { Switch } from 'your-switch-component-library'; // 替换成你用的Switch组件
import { Controller } from 'react-hook-form';

const TableRole = ({ roles, register, control }) => {
  return (
    <table border="1" cellPadding="8">
      <thead>
        <tr>
          <th>角色名称</th>
          {/* 表头渲染权限项 */}
          {roles[0]?.permissions.map(perm => (
            <th key={perm.id}>{perm.permissionKey}</th>
          ))}
        </tr>
      </thead>
      <tbody>
        {roles.map(role => (
          <tr key={role.id}>
            <td>{role.name}</td>
            {/* 为每个权限渲染Switch */}
            {role.permissions.map(perm => {
              const fieldName = `role_${role.id}_perm_${perm.permissionKey}`;
              
              return (
                <td key={perm.id}>
                  {/* 方式1:用register直接绑定(适合原生/简单受控组件) */}
                  <Switch
                    {...register(fieldName)}
                  />

                  {/* 方式2:用Controller绑定(适合自定义组件,更灵活) */}
                  {/* <Controller
                    name={fieldName}
                    control={control}
                    render={({ field }) => (
                      <Switch
                        checked={field.value}
                        onChange={(e) => field.onChange(e.target.checked)}
                      />
                    )}
                  /> */}
                </td>
              );
            })}
          </tr>
        ))}
      </tbody>
    </table>
  );
};

export default TableRole;

关键注意事项

  • 字段唯一性:必须保证每个Switch对应的表单字段名唯一,这里用「角色ID-权限key」的组合可以避免不同角色下相同权限的字段冲突。
  • 数据加载时机:一定要等API数据返回后再用reset设置表单默认值,否则初始为空会导致Switch默认值不显示。
  • 组件适配:如果你的Switch是自定义非受控组件,优先用Controller来集成,能更好地处理值同步问题。

内容的提问来源于stack exchange,提问作者github.arief

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 08:55:17