By Alex Taylor

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!
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.