You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
React-admin relies on a few design decisions that structure its codebase.
8
+
React-admin relies on a several design decisions that structure its codebase.
9
9
10
10
## Single-Page Application
11
11
12
-
React-admin is designed to build Single-Page Applications (SPA). It means that in a react-admin app, the browser fetches the HTML, CSS, and JavaScript required to render the application once, and then only fetches data from APIs through AJAX calls. This is in contrast to traditional web applications, where the browser fetches a new HTML page for each screen.
12
+
React-admin is specifically designed to build [Single-Page Applications (SPA)](https://en.wikipedia.org/wiki/Single-page_application). In a react-admin app, the browser fetches the required HTML, CSS, and JavaScript to render the application only once. Subsequently, data is fetched from APIs through AJAX calls. This is in contrast to traditional web applications, where the browser fetches a new HTML page for each screen.
13
13
14
-
The SPA architecture makes react-admin apps [ultra fast](./Features.md#fast), and allows them to work with existing APIs.
14
+

15
15
16
-
This implies that react-admin uses an internal router (powered by `react-router`) to display the correct screen when the user clicks on a link. To declare routes, developers use the [`<Resource>`](./Resource.md) component for CRUD routes, and the [`<CustomRoutes>`](./CustomRoutes.md) component for other routes.
16
+
The SPA architecture ensures that react-admin apps are [exceptionally fast](./Features.md#fast), easy to host, and compatible with existing APIs without requiring a dedicated backend.
17
17
18
-
For instance, the following react-admin application:
18
+
To achieve this, react-admin utilizes an internal router, powered by `react-router`, to display the appropriate screen when the user clicks on a link. Developers can define routes using the [`<Resource>`](./Resource.md) component for CRUD routes and the [`<CustomRoutes>`](./CustomRoutes.md) component for other routes.
19
+
20
+
For example, the following react-admin application:
Using the `<Resource>` component for CRUD routes allows react-admin to automatically link CRUD pages between them, including for related entities. It lets you think about your application in terms of entities, and not in terms of routes.
56
+
The `<Resource>` component allows react-admin to automatically link CRUD pages between them, including those for related entities. This approach allows you to think about your application in terms of entities, rather than getting bogged down by managing routes.
55
57
56
58
## Providers
57
59
@@ -81,7 +83,7 @@ dataProvider.getList('posts', {
81
83
// }
82
84
```
83
85
84
-
How the `getList()` method translates to an HTTP request is up to the data provider. For instance, when using the REST data provider, the above code will translate to:
86
+
How the `dataProvider.getList()` method translates to an HTTP request is up to the data provider. For instance, when using the REST data provider, the above code will translate to:
85
87
86
88
```
87
89
GET http://path.to.my.api/posts?sort=["title","ASC"]&range=[0, 4]&filter={"author_id":12}
@@ -137,7 +139,7 @@ React-admin was built to avoid rewriting the same code and over again, because m
React-admin isn't a UI Kit like Material UI or Bootstrap. It's a framework that goes beyond presentation to provide building blocks for data-driven applications. It is built on top of material-ui, but you don't need to know material-ui to start using react-admin.
142
+
React-admin isn't a UI Kit like Material UI or Bootstrap. It's a framework that goes beyond presentation to provide building blocks for data-driven applications. It is built on top of Material UI, but you don't need to know Material UI to start using react-admin.
141
143
142
144
For instance, to write a custom menu for your application, you will use the `<Menu>` component:
143
145
@@ -182,19 +184,18 @@ For instance, you cannot pass a list of actions to the `<Edit>` view, but you ca
This allows overriding parts of the logic of a component by composing it with another component.
@@ -274,7 +275,7 @@ React-admin exposes [dozens of hooks](./Reference.md#hooks) to help you build yo
274
275
275
276
## Context: Pull, Don't Push
276
277
277
-
Communicating between components is a common problem in React applications, especially in large ones, when you have to pass props down several levels. React-admin solves this problem by using a pull model: components expose props to their descendants via a context, and descendants can use them via a custom hook.
278
+
Communicating between components is a common problem in React applications. This is especially true in large applications, where you have to pass props down several levels. React-admin solves this problem by using a pull model: components expose props to their descendants via a context, and descendants can use them via a custom hook.
278
279
279
280
Whenever a react-admin component fetches data or defines a callback, the component creates a context and puts the data and callback in it.
This simple approach removes the need for a dependency injection system.
326
327
327
-
So when you write a component that need to access data or callbacks defined higher in the render tree, you can always find a context to get it.
328
+
So when you write a component that needs to access data or callbacks defined higher in the render tree, you can always find a context to get it.
328
329
329
330
Contexts are one of the key concepts in React Admin. If you are not familiar with them, do not hesitate to read the [React documentation on Context](https://react.dev/learn/passing-data-deeply-with-context).
330
331
332
+
## Batteries Included But Removable
333
+
334
+
You can build very complex web apps with react-admin components alone, as long as the react-admin design choices fit yours. But if you need to customize the behavior of a component beyond its existing capabilities, you can always replace a react-admin component with your own.
335
+
336
+
For instance, if [`<SimpleShowLayout>`](./SimpleShowLayout.md) doesn't let you lay out the details of a contact in the following way:
This example comes from [Atomic CRM](https://marmelab.com/react-admin-crm/#/contacts), one of the react-admin demo applications.
403
+
404
+
Never hesitate to replace a react-admin component with your own. React-admin cannot cover all use cases, it provides hooks to plug in your own components, and "It's just React"™.
405
+
406
+
React-admin will never lock you in a corner.
407
+
331
408
## User Experience Is King
332
409
333
410
React-admin has two sets of users:
334
411
335
412
- End users, who use the react-admin app in their browser
336
-
- Developers, who build the react-admin app in their IDE
413
+
- Developers, who use the react-admin code in their IDE
337
414
338
415
For each feature, we design the User Experience (UX) and the Developer Experience (DX) carefully.
339
416
340
-
For the visual part, react-admin builds upon Material UI, which is the implementation of the Material Design System. It's a great help to build usable, consistent user interfaces, but it's not enough.
417
+
For the visual part, react-admin builds upon Material UI, which is the implementation of [Material Design](https://m3.material.io/), a carefully crafted design system for web and mobile apps. It's a great help to build usable, consistent user interfaces, but it's not enough.
341
418
342
419
We spend a great deal of time refining the UI to make it as intuitive as possible. We pay attention to small alignment glitches, screen flashes, and color inconsistencies. We iterate with every customer feedback, to remove visual and animation problems that occur in real-life applications.
343
420
@@ -358,15 +435,15 @@ Many excellent open-source libraries already address partial requirements of B2B
358
435
359
436
Rather than reinventing the wheel, react-admin uses the best tools in each category (in terms of features, developer experience, active maintenance, documentation, user base), and provides a glue around these libraries.
360
437
361
-
In react-admin v4, these libraries are called react-query, react-router, react-hook-form, Material UI, testing-library, date-fns, and lodash.
438
+
In react-admin v4, these libraries are called [react-query](https://tanstack.com/query/v3), [react-router](https://reactrouter.com/en/main), [react-hook-form](https://react-hook-form.com/), [Material UI](https://mui.com/), [emotion](https://emotion.sh/docs/introduction), [testing-library](https://testing-library.com/docs/react-testing-library/intro), [date-fns](https://date-fns.org/), and [lodash](https://lodash.com/).
362
439
363
440
When a new requirement arises, the react-admin teams always looks for an existing solution, and prefers integrating it rather than redeveloping it.
364
441
365
-
There is one constraint, though: all react-admin's dependencies must be compatible with the MIT licence.
442
+
There is one constraint, though: all react-admin's dependencies must be compatible with the [MIT license](https://github.com/marmelab/react-admin/blob/master/LICENSE.md).
366
443
367
444
## Minimal API Surface
368
445
369
-
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 learning curve acceptable, and maintenance burden low.
446
+
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 learning curve acceptable, and the maintenance burden low.
370
447
371
448
For instance, the `<SimpleShowLayout>` component displays Field elements in a column. How can you put two fields in a single column? We could add a specific syntax allowing to specify the number of elements per column and per line. This would complicate the usage and documentation for simple use cases. Besides, it's doable in pure React, without any change in the react-admin core, e.g. by leveraging Material UI's `<Stack>` component:
372
449
@@ -402,41 +479,55 @@ Some components may have a weird API. That's probably for historical reasons. We
402
479
403
480
The code of some components may seem convoluted for no apparent reason. It's probably that the component has to support both the old and the new syntax.
404
481
405
-
This backward compatibility costs a lot in maintenance, and we try to reduce this cost by a good automated test coverage.
482
+
This backward compatibility costs a lot in maintenance to the react-admin core team, but it's a huge time saver for react-admin users.
483
+
484
+
## Principle of Least Surprise
485
+
486
+
Because we favor [composition](#composition), you should be able to combine react-admin components in all sorts of ways, and it should just work (thanks to [contexts](#context-pull-dont-push)). We have an extensive test suite to ensure that the react-admin components work well together. And TypeScript helps you determine when you are using a component in a way that doesn't make sense.
487
+
488
+
This leads to strong design choices in the react-admin code.
489
+
490
+
One of them concerns child inspection, which we tend to avoid at all costs. A counter example is `<Datagrid>`, which inspects its Field children at runtime to determine the column headers. This has serious drawbacks:
491
+
492
+
- If the child is wrapped inside another component that doesn't use the same API, the feature breaks
493
+
- Developers expect that a component affects its subtree, not its ancestors. This leads to inexplicable bugs.
494
+
495
+
We keep child inspection in `<Datagrid>` because there is no better alternative, but it's a rare exception. Every time we implemented child inspection, we regretted it afterward.
496
+
497
+
To avoid surprises, we also avoid `React.cloneElement()`, and passing props down the tree.
406
498
407
499
## Principle Of Least Documentation
408
500
409
501
No one reads docs. It's an unfortunate fact that we have learned to live with.
410
502
411
-
So when we design a new feature, we try to do it in the most intuitive way for developers. We keep the API minimal (see above). We copy the API of well-known libraries. We throw errors with helpful and explicit messages. We provide TypeScript types and JSDoc to help developers discover the API from within their IDE. We publish live examples with commented code.
503
+
So when we design a new feature, we try to do it in the most intuitive way for developers. We keep the API minimal ([see above](#minimal-api-surface)). We copy the API of well-known libraries. We throw errors with helpful and explicit messages. We provide TypeScript types and JSDoc to help developers discover the API from within their IDE. We publish live examples with commented code.
412
504
413
-
When we have to write documentation, it should contain:
505
+
But because react-admin is a very large library, it also has a lengthy documentation. We cover many, many use cases, and our documentation goes beyond basic usage instructions and API description. And to be sure you find the right information quickly, we often duplicate the same information in several places. We believe in the power of [serendipity](https://en.wikipedia.org/wiki/Serendipity).
414
506
415
-
1. images/screencasts
416
-
2. code samples
417
-
3. text
507
+
Don't be afraid if this documentation seems overwhelming at first. You don't need to read it all. You can start with the Introduction chapter of each section, and read the code of the demos. After a while, you'll get used to the react-admin API, and you'll be able to find the information you need quickly.
418
508
419
-
In that order of importance.
509
+
## Monorepo
420
510
421
-
## Inspecting Children Is Bad
511
+
Whenever you import a react-admin component, it's from the `react-admin` package:
422
512
423
-
Some components use child inspection for some features. For instance, the `<Datagrid>` inspects its Field children at runtime to determine the column headers. This has serious drawbacks:
- If the child is wrapped inside another component that doesn't use the same API, the feature breaks
426
-
- Developers expect that a component affects its subtree, not its ancestors. This leads to inexplicable bugs.
517
+
But if you look at [the react-admin source code](https://github.com/marmelab/react-admin) (which we encourage you to do), you will find imports like:
427
518
428
-
Every time we implemented child inspection, we regretted it afterward. We tend to avoid it at all costs, as well as using `React.cloneElement()`.
519
+
```jsx
520
+
import { useListController } from'ra-core';
521
+
```
429
522
430
-
## Monorepo
431
-
432
-
React-admin is a *distribution* of several packages, each of which handles a specific feature. The packages are all located in the `packages/` directory. The most notable packages are:
523
+
In fact, the `react-admin` package only re-exports components from internal packages. React-admin is a *distribution* of several packages, each of which handles a specific feature. The packages are all located in [the `packages/` directory](https://github.com/marmelab/react-admin/tree/master/packages). The most notable packages are:
433
524
434
525
*`ra-core`: The core react-admin logic, without any UI.
435
526
*`ra-ui-materialui`: The Material UI skin for react-admin.
436
527
*`ra-data-*`: Data providers for various data backends.
437
528
*`ra-language-*`: Interface translations for various languages.
438
529
*`react-admin`: the standard distribution of react-admin
439
-
440
-
You can build your own distribution of react-admin by combining different packages.
530
+
531
+
You can build your own distribution of react-admin by combining different packages. You can also import hooks and components directly from one of these packages, if you don't want to import the whole react-admin distribution.
0 commit comments