Friday, 8 March, 2019 UTC


Summary

Oftentimes applications exposing an API need an admin page to easily view and edit the data behind the application. Usually, creating one involves the painstaking process of building an interface, followed by manually creating every request to GET or POST data to/from the API.
react-admin makes this whole process trivial, by automatically consuming your (REST, GraphQL, custom) API and allowing you to quickly build an admin interface, themed with the elegant Material-UI framework.
Today we’ll be building a simple admin interface that uses the JSONPlaceholder fake REST API.

🐊 Alligator.io recommends ⤵

Fullstack Advanced React & GraphQL by Wes Bos
ⓘ About this affiliate link
Installation
To get started, we’re going to create a new React application using create-react-app, and then we’ll install the dependencies for react-admin.
Here we’ll make use of Yarn’s new create command to use Create React App:
$ yarn create react-app admin $ cd admin # Install react-admin dependencies $ yarn add react-admin ra-data-json-server prop-types # Run $ yarn start 
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. Check out the data provider documentation for more information.
Getting Started
First, we’ll open up src/App.js and add in our root Admin component:
src/App.js
import React, { Component } from "react"; import { Admin } from "react-admin"; import jsonServerProvider from "ra-data-json-server"; const dataProvider = jsonServerProvider("https://jsonplaceholder.typicode.com"); class App extends Component { render() { return ( <Admin dataProvider={dataProvider} /> ); } } export default App; 
If we open the application in our browser, we should see a message confirming that react-admin has been properly configured. Now we can start mapping the API endpoints into the admin interface.
Using Guessers
Whenever 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.
src/App.js
import React, { Component } from "react"; import { Admin, Resource, ListGuesser } from "react-admin"; import jsonServerProvider from "ra-data-json-server"; const dataProvider = jsonServerProvider("https://jsonplaceholder.typicode.com"); class App extends Component { render() { return ( <Admin dataProvider={dataProvider}> <Resource name="users" list={ListGuesser} /> </Admin> ); } } export default App; 
In our browser window, we should see the admin interface automatically populate 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’re only there to help us get started. We’re going to take the output from the guesser (which can be found in the DevTools console) and use it to create a custom list component.
This is the output from list guesser:
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:
src/users.js
import React from 'react'; 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 just need to replace the ListGuesser with our newly created component:
src/App.js
// -- snip -- import { UserList } from './users'; class App extends Component { render() { return ( <Admin dataProvider={dataProvider}> <Resource name="users" list={UserList} /> </Admin> ); } } 
Great! In the browser window, we can see that the list works exactly the same. 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:
src/users.js
import React from 'react'; 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> ); 
Much better!
Create, Edit, Delete
Our 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 an easy way to do this as well. We’re going to use a guesser again, but this time, it’s an EditGuesser:
src/App.js
// -- snip -- import { Admin, Resource, EditGuesser } from "react-admin"; import { UserList } from './users'; class App extends Component { render() { return ( <Admin dataProvider={dataProvider}> <Resource name="users" list={UserList} edit={EditGuesser} /> </Admin> ); } } 
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 pretty 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 DisabledInput; you wouldn’t want the id field to be editable!
src/users.js
import React from 'react'; import { List, Datagrid, TextField, EmailField, UrlField, Edit, SimpleForm, TextInput, DisabledInput, } from 'react-admin'; // -- snip -- export const UserEdit = props => ( <Edit {...props}> <SimpleForm> <DisabledInput source="id" /> <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:
src/App.js
// -- snip -- import { UserList, UserEdit } from './users'; class App extends Component { render() { return ( <Admin dataProvider={dataProvider}> <Resource name="users" list={UserList} edit={UserEdit} /> </Admin> ); } } 
Now we have a functional edit interface! Unfortunately, JSONPlaceholder doesn’t allow edits. However, try to edit a user and see what happens. You should see 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 just 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.
src/users.js
import React from 'react'; import { List, Datagrid, TextField, EmailField, UrlField, Edit, SimpleForm, TextInput, DisabledInput, Create } from 'react-admin'; // -- snip -- 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:
src/App.js
// -- snip -- import { UserList, UserEdit, UserCreate } from './users'; class App extends Component { render() { return ( <Admin dataProvider={dataProvider}> <Resource name="users" list={UserList} edit={UserEdit} create={UserCreate} /> </Admin> ); } } 
And just like that, react-admin will add a “Create” button to our list of users!
More Information
We’ve created a nice little admin interface using react-admin, but we’ve barely scratched the surface of what is 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, see the react-admin documentation.
The full code for this post is available on CodeSandbox.