React-admin V4: Persistent Preferences

François Zaninotto
François ZaninottoApril 05, 2022
#react#react-admin#tutorial

A major version is usually about breaking changes, and not about new features. Yet, react-admin v4 introduces a new set of features centered around User Experience and preferences. Let's look at these features.

Persistent Language and Theme Choice

Many B2B apps offer users the ability to change the language and the theme of the app. In react-admin v3, end-users had to make this change for every session.

Starting with react-admin v4, these changes are persistent, leveraging the browser's local storage. Whenever a user opens a react-admin app that they have customized in the past, they will see it as they left it - with the right language and theme.

TogglethemeButton

Even better: When a user has opened an app in several tabs, changes to the language or theme done in one tab are immediately reflected in the other tabs.

Use these features through 2 new components: <LocalesMenuButton> lets users choose a language, and <ToggleThemeButton> lets them switch between light and dark themes. These buttons are often inserted in a custom App Bar:

import { AppBar, LocalesMenuButton, ToggleThemeButton } from 'react-admin';

const MyAppBar = props => (
    <AppBar {...props}>
        <Box flex="1">
            <Typography variant="h6" id="react-admin-title"></Typography>
        </Box>
        <LocalesMenuButton
            languages={[
                { locale: 'en', name: 'English' },
                { locale: 'fr', name: 'Français' },
            ]}
        />
        <ToggleThemeButton lightTheme={lightTheme} darkTheme={darkTheme} />
    </AppBar>
);

Persistent Sort and Filters

In List views, when users change the filters or the sort order, react-admin keeps this choice in memory. That way, when users come back to a list they have modified in the past, they will see the same filters and sort order. This User Experience, akin to mobile applications, is expected in modern B2B apps.

But in v3, these choices were lost at the end of the user session (as soon as they closed the app or their browser). In react-admin v4, these choices are now persistent between sessions (once again using the browser's local storage). When reopening an app, a user will find the lists in exactly the same way they left them.

Persistent Filters

This feature is automatic and requires no code change.

Tip: When a user logs out, the browser local storage is cleared, and the list filters and sort order are reset.

Saved Queries

Saved Queries, a new feature in react-admin v4, let users save a combination of filters and sort parameters into a new, personal filter.

SavedQueriesList

Saved queries persist between sessions, so users can find their custom queries even after closing and reopening the admin.

Saved queries are enabled by default in the Filter Button/Form combo. They are opt-in for the <FilterList> Sidebar, via the new <SavedQueriesList>component:

import {
    SavedQueriesList,
    FilterList,
    FilterListItem,
    List,
    Datagrid,
} from 'react-admin';
import { Card, CardContent } from '@mui/material';

const SongFilterSidebar = () => (
    <Card>
        <CardContent>
            <SavedQueriesList />
            <FilterList label="Record Company" icon={<BusinessIcon />}>
                ...
            </FilterList>
            <FilterList label="Released" icon={<DateRangeeIcon />}>
                ...
            </FilterList>
        </CardContent>
    </Card>
);

const SongList = props => (
    <List {...props} aside={<SongFilterSidebar />}>
        <Datagrid>...</Datagrid>
    </List>
);

Introducing The Store

All the new features above rely on a few hooks that allow react-admin to interact with a global, synchronous, persistent store called... "The Store". Think of the Store as a key-value database that persists between page loads.

The store uses the browser local storage (or memory storage when localStorage isn’t available). The store is emptied when the user logs out. It requires no setup, and is available via the useStore hook:

import { useStore } from 'react-admin';
import { Button, Popover } from '@mui/material';

const HelpButton = () => {
    const [helpOpen, setHelpOpen] = useStore('help.open', false);
    return (
        <>
            <Button onClick={() => setHelpOpen(v => !v)}>
                {helpOpen ? 'Hide' : 'Show'} help
            </Button>
            <Popover open={helpOpen} onClose={() => setHelpOpen(false)}>
                French
            </Popover>
        </>
    );
};

useStore should remind you of the useState hook. It takes a key and a default value. It returns an array of 2 values: the current value of the key, and a function to update it.

The store can contain values of any type (e.g. string, number, boolean, array, object), as long as they can be serialized with JSON.stringify().

You can use the Store to extend the preferences of your app. For example, you can store the width of the sidebar (if it's resizable), or the open/closed menus (if you use multi-level navigation).

These Features Used To Be An EE Exclusive

These features were previously available only in the Enterprise Edition (EE) of react-admin, as part of the ra-preferences package.

But, to our disappointment, this package is the least used of the Enterprise Edition packages. It's disappointing because, in our opinion, it's a crucial tool to offer a good user experience. But EE customers seem to be more interested in having ready-to-use solutions for complex business logic (like RBAC or tree structures). Or maybe we didn't advertise these features enough. Anyway.

One of our mottos in react-admin is "User Experience Is King". It was logical to port these features to the Open-Source version of react-admin, and to offer them for free. That's why they are now standard in react-admin v4.

Conclusion

React-admin v4 is a huge step forward. Apps built with this new version are not only a pleasure to develop, but they also provide a better user experience.

If you want a glimpse of the future of react-admin, check out the Store chapter in the react-admin v4 documentation.

Did you like this article? Share it!