Applications exposing an API will often need an administrator (admin) page to view and edit the data behind the application. Creating one usually requires the painstaking process of building an interface, followed by manually handling every request to GET or POST data to and from the API.
react-admin
reduces this drudgery by automatically consuming your (REST, GraphQL, custom) API and allowing you to quickly build an admin interface themed with the elegant Material-UI framework.
In this article, you will use react-admin
to build an admin interface that uses the JSONPlaceholder API.
This tutorial was verified with Node v16.6.1, npm
v7.20.3, react
v17.0.2, react-admin
vv3.17.1, and ra-data-json-server
v3.17.1.
To get started, we’re going to create a new React application using create-react-app
:
- npx create-react-app react-admin-example
Next, navigate to the new project directory:
- cd react-admin-example
Then, install the dependencies for react-admin
:
- npm install react-admin@<3.17.1^> ra-data-json-server@3.17.1<^>
ra-data-json-server
is what’s called a data provider. Data providers are what allow react-admin
to communicate with your API. Here, we’re using ra-data-json-server
because JSONPlaceholder is powered by JSON Server. If you’re using an API that doesn’t exactly match that of JSONPlaceholder, you will need to implement your own data provider. Consult the data provider documentation for more information.
At this point, you have a new React project with react-admin
and ra-data-json-server
installed.
First, we’ll open up src/App.js
in our code editor and add in our root Admin
component:
import {
Admin
} from 'react-admin';
import jsonServerProvider from 'ra-data-json-server';
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
function App() {
return (
<Admin dataProvider={dataProvider} />
);
}
export default App;
Save the changes to your file and run the application:
- npm run start
Then, open the application in our browser. It will display a message confirming that react-admin
has been properly configured:
OutputWelcome to React-admin
Your application is properly configured.
Now you can add a <Resource> as child of <Admin>.
Now, we can start mapping the API endpoints into the admin interface.
ListGuesser
to Map DataWhenever you add a new endpoint, you first use a guesser. This will take the data from the API and guess what kind of component to output. The first endpoint we’ll add is users
, and we’re going to use ListGuesser
to automatically render a list of all users:
import {
Admin,
Resource,
ListGuesser,
} from 'react-admin';
import jsonServerProvider from 'ra-data-json-server';
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
function App() {
return (
<Admin dataProvider={dataProvider}>
<^><Resource
name="users"
list={ListGuesser}
/>
</Admin>
);
}
export default App;
Save the changes to your file and observe the application in your browser.
There is an admin interface that is automatically populated with a list of users! Including their names, emails, phone number, and more!
It works almost perfectly but guessers aren’t meant to be used permanently. They are only there to help us get started. We’re going to take the guessed list output from the guesser (which can be found in the DevTools console) and use it to create a custom list component:
export const UserList = (props) => (
<List {...props}>
<Datagrid rowClick="edit">
<TextField source="id" />
<TextField source="name" />
<TextField source="username" />
<EmailField source="email" />
<TextField source="address.street" />
<TextField source="phone" />
<TextField source="website" />
<TextField source="company.name" />
</Datagrid>
</List>
);
We’ll take this output and paste it into a new file called Users.js
, while making sure to add all the imports from react-admin
:
import {
List,
Datagrid,
TextField,
EmailField,
} from 'react-admin';
export const UserList = (props) => (
<List {...props}>
<Datagrid rowClick="edit">
<TextField source="id" />
<TextField source="name" />
<TextField source="username" />
<EmailField source="email" />
<TextField source="address.street" />
<TextField source="phone" />
<TextField source="website" />
<TextField source="company.name" />
</Datagrid>
</List>
);
Now we need to replace the ListGuesser
with our newly created component:
import {
Admin,
Resource,
} from 'react-admin';
import jsonServerProvider from 'ra-data-json-server';
import {
UserList,
} from './Users';
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
function App() {
return (
<Admin dataProvider={dataProvider}>
<Resource
name="users"
list={UserList}
/>
</Admin>
);
}
export default App;
Great! In the browser window, we can verify that the list works exactly as it did with ListGuesser
.
Let’s make some changes to UserList
to make it a little better. We’ll change the website
column to a UrlField
to make it clickable. We’ll also add a label to the address
and company
columns to make it a bit more readable:
import {
List,
Datagrid,
TextField,
EmailField,
UrlField,
} from 'react-admin';
export const UserList = props => (
<List {...props}>
<Datagrid rowClick="edit">
<TextField source="id" />
<TextField source="name" />
<TextField source="username" />
<EmailField source="email" />
<TextField source="address.street" label="Address" />
<TextField source="phone" />
<UrlField source="website" />
<TextField source="company.name" label="Company" />
</Datagrid>
</List>
);
Instead of Address.street the label displays as Address. Instead of Company.name the label displays as Company. Much better!
EditGuesser
to Map Create, Edit, DeleteOur admin interface works great if you’re just trying to view users, but what if you want to create, edit, or even delete users? Thankfully, react-admin
has a way to do this as well. We’re going to use a guesser again, but this time, it’s an EditGuesser
:
import {
Admin,
Resource,
EditGuesser,
} from "react-admin";
import jsonServerProvider from 'ra-data-json-server';
import {
UserList,
} from './Users';
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
function App() {
return (
<Admin dataProvider={dataProvider}>
<Resource
name="users"
list={UserList}
edit={EditGuesser}
/>
</Admin>
);
}
export default App;
Now, let’s open up the admin in our browser and click on any user. This will bring up the edit interface, and once again, the guesser does a good job!
We’re going to do the same thing as before and copy the output from the guesser and paste it into our Users.js
file. We’re also going to change the id
column to a disabled
input; you wouldn’t want the id
field to be editable!
import {
List,
Datagrid,
TextField,
EmailField,
UrlField,
Edit,
SimpleForm,
TextInput,
} from 'react-admin';
export const UserList = props => ( ... );
export const UserEdit = props => (
<Edit {...props}>
<SimpleForm>
<TextInput source="id" disabled />
<TextInput source="name" />
<TextInput source="username" />
<TextInput source="email" />
<TextInput source="address.street" label="Address" />
<TextInput source="phone" />
<TextInput source="website" />
<TextInput source="company.name" label="Company" />
</SimpleForm>
</Edit>
);
And finally, replace the EditGuesser
with our custom component:
import {
Admin,
Resource,
} from "react-admin";
import jsonServerProvider from 'ra-data-json-server';
import {
UserList,
UserEdit,
} from './Users';
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
function App() {
return (
<Admin dataProvider={dataProvider}>
<Resource
name="users"
list={UserList}
edit={UserEdit}
/>
</Admin>
);
}
export default App;
Now we have a functional edit interface! Unfortunately, JSONPlaceholder doesn’t allow edits. However, try to edit a user and observe what happens. You will experience the user change for a second before react-admin
changes it back to its original form. This is because react-admin
uses optimistic rendering. This means that when a user makes a change, react-admin
displays that change immediately while sending an update query in the background. This allows for a seamless user experience, with no need to wait for a server response before updating the admin interface.
The only thing we’re missing now is a way to create new users. Since the creation form is so similar to the edit form, we can copy our UserEdit
component and call the new component UserCreate
. Make sure to remove the id
field, since the user can’t have an id
before creation.
import {
List,
Datagrid,
TextField,
EmailField,
UrlField,
Edit,
SimpleForm,
TextInput,
Create,
} from 'react-admin';
export const UserList = props => ( ... );
export const UserEdit = props => ( ... );
export const UserCreate = props => (
<Create {...props}>
<SimpleForm>
<TextInput source="name" />
<TextInput source="username" />
<TextInput source="email" />
<TextInput source="address.street" label="Address" />
<TextInput source="phone" />
<TextInput source="website" />
<TextInput source="company.name" label="Company" />
</SimpleForm>
</Create>
);
Now add the new component to App.js
:
import {
Admin,
Resource,
} from "react-admin";
import jsonServerProvider from 'ra-data-json-server';
import {
UserList,
UserEdit,
UserCreate,
} from './Users';
const dataProvider = jsonServerProvider('https://jsonplaceholder.typicode.com');
function App() {
return (
<Admin dataProvider={dataProvider}>
<Resource
name="users"
list={UserList}
edit={UserEdit}
create={UserCreate}
/>
</Admin>
);
}
export default App;
And just like that, react-admin
will add a Create button to our list of users!
In this article, you used react-admin
to build an admin interface that uses the JSONPlaceholder) API.
We’ve created a nice little admin interface using react-admin
, but we’ve barely scratched the surface of what it has to offer. react-admin
is highly customizable: the functionality and appearance of every component we’ve used so far (and more) can be customized. To learn more, consult the react-admin
documentation.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!