【问题标题】:Updated Value of custom Input in React-Admin not getting submitted in edit formReact-Admin 中自定义输入的更新值未在编辑表单中提交
【发布时间】:2020-07-13 03:11:13
【问题描述】:

我正在尝试在 React-Admin 中使用名为“UserRolesSelect”的自定义输入字段构建一个编辑表单,该字段显示来自单独角色端点的角色列表,其中当前用户的角色被选中。但是,在发出编辑请求时,自定义输入的值不会在表单数据中更新。我提供了来自上述两个端点的示例响应。

// sample response for getting user details by ID
const user = {
id:1,
name:'User1',
email:'user1@user.com',
created_at:2020-04-01T10:43:36.000000Z,
roles:[{id:1,name:'User'}]
};

// sample response of getting roles list
const roles = [
{id: 1,
name: 'user'},
{id: 2,
name: 'admin'}
]


const UserRolesSelect = ({ source, record }) => {
    const [selectedRoles, setRoles] = useState([]);

    useEffect(() => {
        const userRoles = record.roles.map(role => role.id);
        setRoles(userRoles);
    }, []);

    const { data, loading: rolesLoading, error: rolesError } = useQuery({
        type: 'getList',
        resource: 'roles',
    });

    if (rolesLoading) return <Loading />;
    if (rolesError) return <Error />;
    if (!data) return null;

    const rolesList = data.map(role => <MenuItem key={role.id} value={role.id} selected={selectedRoles}>
        {role.name}
    </MenuItem>);

    const handleChangeMultiple = event => {
        const { value: role } = event.target;
        const value = [...role];
        setRoles(value);
    };

    return <Select
        value={selectedRoles}
        onChange={handleChangeMultiple}
        multiple
    >
        {rolesList}
    </Select>
};

const UserEdit = props => {
    return <Edit {...props}>
            <SimpleForm >
                <TextInput source="name" />
                <TextInput source="email" />
                <UserRolesSelect source="roles"/>
            </SimpleForm>
        </Edit>
};

【问题讨论】:

    标签: reactjs react-admin react-final-form


    【解决方案1】:

    您的自定义元素会更新其内部状态,但不会将更改传达给外界。要更改表单值,您必须使用 &lt;Field&gt; 组件或 useField() 挂钩 - 两者都来自 react-final-form,这是 react-admin 内部使用的表单框架。

    对于您的示例,这将给出如下内容:

    const UserRolesSelect = ({ source }) => {
        const { input, meta } = useField(source);
        // the current value is in input.value
        // the callback to change the value is in input.onChange
        ...
    };
    

    react-admin 文档中有一个部分详细解释了如何编写自定义表单,我建议你先阅读它。

    https://marmelab.com/react-admin/Inputs.html#writing-your-own-input-component

    此外,您似乎正在尝试重新创建 react-admin 中已经存在的功能。请参阅 ReferenceArrayInput 的文档。

    https://marmelab.com/react-admin/Inputs.html#referencearrayinput

    【讨论】:

    • 非常感谢您的帮助。我确实尝试使用 ReferenceArrayInput 但我无法让它与两个资源一起使用,即我无法从角色端点获取角色,然后根据特定用户的角色将某些角色标记为选中另一个端点。你能告诉我这样做的正确方法是什么吗?因为这将消除对自定义输入的需求并大大简化事情。
    【解决方案2】:

    有完全相同的情况 - 需要一点时间开始以 react-admin 风格思考,但它看起来很漂亮。我建议以下策略:

    在您的用户对象中保存角色 ID 的数组。 (为了方便,我在服务器上附加了一个带有角色对象的数组)

    const user = {
      id:1,
      name:'User1',
      email:'user1@user.com',
      created_at:2020-04-01T10:43:36.000000Z,
      roles:[{id:1,name:'User'}, {id:2,name:'Manager'}],
      rolesIds:[1, 2]
    };
    

    那么你应该使用的是以下组合:

     <ReferenceArrayInput label="Roles" reference={"roles"} source="rolesIds">
             <SelectArrayInput optionText={roleRender} />                    
     </ReferenceArrayInput> 
    
    ...
        const roleRender = role => role.name;
    

    通过这种方式,您可以从roles 端点收集选项集,并将对象数组rolesIds 中的内容标记为已选择。

    【讨论】:

      猜你喜欢
      • 2019-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多