简体   繁体   中英

React-admin: How to create user profile form in react-admin v3.2.*?

I've noticed that the official article on how to create user settings (profile) in React-Admin is outdated ( https://marmelab.com/blog/2019/03/07/react-admin-advanced-recipes-user-profile.html ).

I followed the example and tried to use a new DataProvider , but couldn't get Edit view working (it just showed blank Card component with no fields even though I've set them in a way that's described in the example).

I was searching for several days on how to implement it in a simplest/clean way, but there's a very small amount of information about it.

Does somebody know how to do it in react-admin 3.2.*?

It might be helpful for others who have the same issue. Any help will be very appreciated! Thanks!

I had the same problem. Looking at the props passed toreact-admin's Edit , I saw the record prop was undefined. It was because the id field inside the record returned by the data provider's getOne method was different than the id prop hardcoded on the Edit component. Once that was set to match, both reading/editing works.

My working code:

// remove staticContext to avoid React 'unknown prop on DOM element' error
export const PrincipalEdit = ({ staticContext, ...props }: { staticContext: any; props: any }) => {
  return (
    // `id` has to match with `id` field on record returned by data provider's `getOne`
    // `basePath` is used for re - direction
    // but we specify no redirection since there is no list component
      <Edit {...props} title="My Profile" id="my-profile" resource={b.PRINCIPAL} basePath="my-profile" redirect={false}>
        <SimpleForm>
          <TextInput source="firstName" validate={required()} />
        </SimpleForm>
      </Edit>
  );
};

The issue is how the data is stored by react-admin at the moment (haven't checked how it was before). Now each data entry is saved by its id in the store object (the reasons are obvious). I think the best approach is to modify the data provider.

if (resource === 'profile') {
  const { id, ...p } = params; // removes the id from the params
  if (p.data)
    delete p.data.id; // when updates there is data object that is passed to the backend

  return dataProvider(type, resource, { ...p, id: '' }) // set the id just empty string to hack undefined as http param
    .then(({ data }) => {
      return Promise.resolve({
        data: {
        ...data,
          id // return the data with the initial id
        }
      });
    });
}

This way the backend endpoint could return just the object at the main endpoint of the entity /profile . If you do not set the id prop to '' it will try to fetch /profile/undefined because the id prop was deleted from the params object. If you do not delete the id prop from the data object when updating, depending on the backend sql query (assuming you are using some kind of db) for updating a record, it may try to set or search by this id.

In the Edit component you can pass whatever id you want but something must be passed.

Additional: If you are using NestJS as backend with the Crud package, these @Crud params may be helpful

  ...
  params: {
    id: { // the routes won't have params, very helpful for me/profile controller
      primary: true,
      disabled: true,
    },
  },
  routes: {
    only: ["getOneBase", "updateOneBase"],
  },
  ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM