Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BC Break] Retire redux #7177

Merged
merged 9 commits into from
Feb 3, 2022
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
577 changes: 330 additions & 247 deletions UPGRADE.md

Large diffs are not rendered by default.

90 changes: 0 additions & 90 deletions docs/Admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,8 @@ Here are all the props accepted by the component:
- [`menu`](#menu)
- [`theme`](#theme)
- [`layout`](#layout)
- [`customReducers`](#customreducers)
- [`loginPage`](#loginpage)
- [`logoutButton`](#logoutbutton)
- [`initialState`](#initialstate)
- [`history`](#history)
- [`basename`](#basename)
- [`ready`](#ready)
Expand Down Expand Up @@ -335,59 +333,6 @@ export default MyLayout;

For more details on custom layouts, check [the Theming documentation](./Theming.md#using-a-custom-layout).

## `customReducers`

The `<Admin>` app uses [Redux](https://redux.js.org/) to manage state. The state has the following keys:

```json
{
"admin": { /*...*/ }, // used by react-admin
"routing": { /*...*/ }, // used by connected-react-router
}
```

If your components dispatch custom actions, you probably need to register your own reducers to update the state with these actions. Let's imagine that you want to keep the bitcoin exchange rate inside the `bitcoinRate` key in the state. You probably have a reducer looking like the following:

```jsx
// in src/bitcoinRateReducer.js
export default (previousState = 0, { type, payload }) => {
if (type === 'BITCOIN_RATE_RECEIVED') {
return payload.rate;
}
return previousState;
}
```

To register this reducer in the `<Admin>` app, simply pass it in the `customReducers` prop:

{% raw %}
```jsx
// in src/App.js
import * as React from "react";
import { Admin } from 'react-admin';

import bitcoinRateReducer from './bitcoinRateReducer';

const App = () => (
<Admin customReducers={{ bitcoinRate: bitcoinRateReducer }} dataProvider={simpleRestProvider('http://path.to.my.api')}>
...
</Admin>
);

export default App;
```
{% endraw %}

Now the state will look like:

```json
{
"admin": { /*...*/ }, // used by react-admin
"routing": { /*...*/ }, // used by connected-react-router
"bitcoinRate": 123, // managed by rateReducer
}
```

## `loginPage`

If you want to customize the Login page, or switch to another authentication strategy than a username/password form, pass a component of your own as the `loginPage` prop. React-admin will display this component whenever the `/login` route is called.
Expand Down Expand Up @@ -423,38 +368,6 @@ const App = () => (
);
```

## `initialState`

The `initialState` prop lets you pass preloaded state to Redux. See the [Redux Documentation](https://redux.js.org/docs/api/createStore.html#createstorereducer-preloadedstate-enhancer) for more details.

It accepts either a function or an object:

```jsx
const initialState = {
theme: 'dark',
grid: 5,
};

const App = () => (
<Admin initialState={initialState} dataProvider={simpleRestProvider('http://path.to.my.api')}>
// ...
</Admin>
);
```

```jsx
const initialState = () => ({
theme: localStorage.getItem('theme'),
grid: localStorage.getItem('grid'),
});

const App = () => (
<Admin initialState={initialState} dataProvider={simpleRestProvider('http://path.to.my.api')}>
// ...
</Admin>
);
```

## `history`

**Note**: This prop is deprecated. Check [the Routing chapter](./Routing.md) to see how to use a different router.
Expand Down Expand Up @@ -687,6 +600,3 @@ When a user browses to `/register`, the `<Register>` component will appear outsi

**Tip**: Custom routes can be [a `<Redirect>` route](https://reacttraining.com/react-router/web/api/Redirect), too.

## Using react-admin without `<Admin>` and `<Resource>`

Using `<Admin>` and `<Resource>` is completely optional. If you feel like bootstrapping a redux app yourself, it's totally possible. Head to [Including in another app](./CustomApp.md) for a detailed how-to.
6 changes: 0 additions & 6 deletions docs/Architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,6 @@ const MyRefreshButton = () => {
};
```

## Redux As An Implementation Detail

React-admin uses [Redux](https://react-redux.js.org/) for some of its state management. Redux has performance advantages over pure React contexts. But we don't document the action creators or the Redux state, because we see Redux as an implementation detail. Instead of dispatching actions, react-admin developers use hooks.

Previous versions of react-admin used to put a greater emphasis on Redux. It's no longer the case, and we even consider that we could remove Redux completely in the future - if React ever implements Context selectors.

## Minimal API Surface

Before adding a new hook or a new prop to an existing component, we always check if there isn't a simple way to implement the feature in pure React. If it's the case, then we don't add the new prop. We prefer to keep the react-admin API, code, test, and documentation simple. This choice is crucial to keep the maintenance burden low, and the learning curve acceptable.
Expand Down
2 changes: 1 addition & 1 deletion docs/Authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ export default {

### Logout Configuration

If you enable authentication, react-admin adds a logout button in the user menu in the top bar (or in the sliding menu on mobile). When the user clicks on the logout button, this calls the `authProvider.logout()` method, and removes potentially sensitive data from the Redux store. Then the user gets redirected to the login page. The two previous sections also illustrated that react-admin can call `authProvider.logout()` itself, when the API returns a 403 error or when the local credentials expire.
If you enable authentication, react-admin adds a logout button in the user menu in the top bar (or in the sliding menu on mobile). When the user clicks on the logout button, this calls the `authProvider.logout()` method, and removes potentially sensitive data sored in [the react-admin Store](./Store.md). Then the user gets redirected to the login page. The two previous sections also illustrated that react-admin can call `authProvider.logout()` itself, when the API returns a 403 error or when the local credentials expire.

It's the responsibility of the `authProvider.logout()` method to clean up the current authentication data. For instance, if the authentication was a token stored in local storage, here is the code to remove it:

Expand Down
244 changes: 0 additions & 244 deletions docs/CustomApp.md

This file was deleted.

1 change: 0 additions & 1 deletion docs/Theming.md
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,6 @@ const MyLayout = ({
title,
}) => {
const classes = useStyles();
const dispatch = useDispatch();
const [open] = useSidebarState();

return (
Expand Down
1 change: 0 additions & 1 deletion docs/TreeWithDetails.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ const App = () => (
dataProvider={dataProvider}
i18nProvider={i18nProvider}
locale="en"
customReducers={{ tree }}
>
<Resource list={CategoriesList} />
</Admin>
Expand Down
Loading