Closed fzaninotto closed 2 years ago
Hi I have a question, what drives the decision to replace redux-form to react-final-form during v2->v3 and then switch to formik from v3->v4? License? Render speed?
I know the main interface of form components won't change much, but some of the attributes of the components may get changed.
You also mentioned removing redux-saga. Currently there are still a lot of parts related to the saga in the codebase, including handling of authentications and data fetchings.
Is the alternative going to be using react contexts? That is probably the only method to replace saga. Thanks!
In terms of this major release, will ra-enterprise version also receive new versions in parallel? I am pretty interested in the paid version so I have so many questions to discuss here.
Hi I have a question, what drives the decision to replace redux-form to react-final-form during v2->v3 and then switch to formik from v3->v4? License? Render speed?
The same reason: library maintenance. redux-form
isn't maintained anymore, and react-final-form
is taking the same path. some bugs in react-admin can't be fixed because they are caused by bugs in final-form that don't get fixed.
On the other hand, formik is actively maintained and has a positive contribution curve.
Finally, react-final-form has 6k stars on GitHub, while Formik has 26k stars. When we made the choice to go with final-form, they were at the same level.
Currently there are still a lot of parts related to the saga in the codebase, including handling of authentications and data fetchings.
No, 100% of the side effects are handled by pure React side effects and contexts in the curent codebase. The sagas are just here for backwards compatibility.
will ra-enterprise version also receive new versions in parallel?
We'll make re-enterprise modules compatible with 4.0 as soon as it's released. If this can be done without breaking change, then this will be a minor release, otherwise it'll be a major release.
react-hook-form
Suggest
It would probably be nice to introduce hooks to trigger side effects which could update the store. It would help implementing custom data providers methods which may have to update the data, delete it, etc.
For example see #5959. With a useDeleteFromStore
or similar, it would be trivial to implement
The <AutocompleteInput />
could be rewritten to use the <Autocomplete />
from Material-UI. In V5 it will not be in beta anymore.
Extend the permissions
action to more components. In particular, the <Fields>
and <Inputs>
components.
A fairly common task is to restrict user fields based on access.
Now, each of my <Fields>
and <Inputs>
components is wrapped in an accessor function. This makes the components <List>
, <Show>
, <Edit>
and others very cumbersome.
It would be nice if as many components as possible support the access property.
Or, for example, for example, to be able to specify access in the style of validation of both the form and individual fields.
Replace react-final-form with formik
Did you think about integrating https://github.com/react-hook-form/react-hook-form instead of formik? react-final-form
and formik
are crazy slow and unoptimized when working with semi large and large forms (10+ inputs or array input).
react-hook-form
is really fast with hundreds of inputs and also isolates rerenders based on the state chunks that changed. Main difference is uncontrolled approach but that can be solved with https://react-hook-form.com/advanced-usage#ControlledmixedwithUncontrolledComponents.
Aside from that APIs are similar (we recently replaced formik with react-hook-form in one of our projects with no issues).
People are already moving from formik based on the reasons above so maybe think about jumping to react-hook-form
?
It is not a huge difference but I was wondering why do you depend on classnames
when material-ui (and probably some others) already depend on clsx
?
Passed my mind when thought about reducing dependencies list.
@ValentinnDimitroff No idea when they migrated to clsx. When we started using material-ui, they were using classnames.
I guess we focus more on backwards compatibility and they prefer to move fast and break things ;)
You mention that you plan on removing redux-saga
and saga-based side effects
. While I don't pass through any customSagas
to the Admin
component yet, I am looking at ways to dispatch notification actions from whenever a specific event occurs. For instances like this useNotify
isn't a viable option.
Is there a migration strategy for those that are using customSagas in such a way, or will the customSagas
property still be supported?
I am looking at ways to dispatch notification actions whenever a specific event occurs
Do like we do in the react-admin codebase: combine useNotify
and useEffect
.
Remove redux-saga and saga-based side effects
May I ask what lead to the decision to remove redux-saga? What was it used for and how is it replaced now?
It was used for side effects, and we now use useSideEffect
for that. Besides, when we first built react-admin, Redux was the cornerstone of the state and change management. Today, Redux isn't so central, and some newer parts of the framework simply don't rely on it at all (e.g. authentication).
As an example, the react-admin demo doesn't use saga at all.
@sidescraper please don't post feature requests here. We're adding new features in minor versions. 4.0 will probably add no new feature, but just change the underlying layers that have become a problem. It's all about breaking backwards compatibility.
Does moving to formik
mean that any custom forms will need to be rewritten more or less from scratch? Or will there be a compatibility layer for a couple of versions?
The move to formik will be a breaking change, but for most custom forms, the required change will reduce to changing the package name as the APIs are mostly compatible:
-import { Form, Field } from 'react-final-form';
+import { Form, Field } from 'formik';
what does the community think about react-hook-form ? I think it's more user friendly when compared to formik.
I would prefer formik since it it introduces minimal breaking change
EDIT 8/3/2021: After more evaluation of react-hook-form 5 month later after the initial post, it seems the react-hook-form's development is more active, and it also has smaller bundle size. We have already switched to react-hook-form on some other projects.
What do you think about removing extra styles? This change will make the components more clearer and compatible with the Material-UI API.
I will try to explain in more detail.
For example, when using <SearchInput />
, I expect the position on the page to be similar to the <TextField />
, without additional margin
.
Or when using <SelectInput />
, responsiveness sometimes breaks on small screens due to min-width
.
Other components have similar additional styles. makeStyles
can be overridden, but it seems to me that in some cases the components would be more convenient without them.
@Lukin I don't understand the problem you're trying to solve. Could you elaborate?
@Lukin If I understand your suggestion correctly this would break the default FormLayouts. Or do you expect these layouts to inject the custom styles?
@fzaninotto Yes, that's right. I often have to use custom complex form layouts. By injecting these styles into included layouts (e.g. SimpleForm, TabbedForm), field and input components would be more flexible.
Extend the
permissions
action to more components. In particular, the<Fields>
and<Inputs>
components. A fairly common task is to restrict user fields based on access. Now, each of my<Fields>
and<Inputs>
components is wrapped in an accessor function. This makes the components<List>
,<Show>
,<Edit>
and others very cumbersome. It would be nice if as many components as possible support the access property. Or, for example, for example, to be able to specify access in the style of validation of both the form and individual fields.
@wmwart I know this isn't the best place for this message, but I just open sourced this handy package to do just that: https://github.com/andrico1234/ra-acl. It's inspired by Marmelab's ra-auth-acl, and adds hooks and declarative components.
Please make HRM work with React-Admin!
Please support next-auth as authentication provider
@VinayaSathyanarayana Please don't post comments with feature requests that don't need a breaking change here. React-admin releases new features on a daily basis, and doesn't need a major release for that. This discussion is only for backwards-incompatible changes.
Thanks for the clarification @fzaninotto. Apologies as I failed to note this thread was only for backward compatibility issues.
Do you think that it would be possible to add stronger typing to resources (Resource<MyResourceType>
) instead of using Record everywhere (which is based on [key: string]: any
)?
Same remark as above: this doesn't imply a BC break, please don't use this conversation for feature requests.
@fzaninotto, ok.
It seems difficult to me to say what implies a BC and what doesn't. It seemed to me that this modification would deeply change the way RA is used. Maybe I'm missing something.
I'll post this in a separate feature request.
@fzaninotto,
What do you think about using react-query or swr instead of using redux
?
@ckoliber What do you think these libs would bring to react-admin that it doesn't already have?
I'm adding one possible breaking change: updating the format of the filters parameter passed to getList.
Currently, the filters are passed as key: value
, e.g.:
{ filter: { name: "John Doe" } }
Which doesn't allow an operator. When developers want to use operators like greater than, includes, not equal, they currently have no standard way of doing so. We've got around this in demos by appending operators to the key name, but that's neither standard or explicit:
{ filter: { name_neq: "John Doe" } }
We should pass filters as an array of conditions, each condition being a field, an operator, and a value.
{ filter: [{ key: "name", operator: "NOT_EQUALS", value: "John Doe" }] }
dataProviders would then do what they want to convert that to their API syntax.
Cons: This would significantly increase the difficulty to build a dataProvider, and break all existing providers. Besides, not all backends support such operators, so basing a feature on the existence of these operators (like a date interval filter) would exclude some backends.
What do you think?
@fzaninotto
Using redux as a server state
library, causes the increasing of codebase and increasing the bugs caused by reimplemening the wheel from scratch, and also there are a lot of features that you never need to reimplement them like:
@fzaninotto
A great and common way of writing queries in JSON
or Object
format is using MongoDB Query Language, handling where
conditions using nested objects
Currently these dataProviders are using this structure for handling filters, and I think the current state of react-admin filters is great and no need to change
In regards to filters I also think it is better to keep them simple and everyone can implement their own layer for advanced filtering. This also keeps initial learning curve nice and easy.
Using redux as a
server state
library, causes the increasing of codebase
Our internal data store, implemented with Redux, provides optimistic rendering in CRUD actions. No other library provides that type of abstraction. So yes, the codebase is larger than a simple query builder, because it does much more than that.
and increasing the bugs caused by reimplemening the wheel from scratch,
I disagree. We haven't recreated redux-libray or swr libraries from scratch ; they were created after react-admin. Also, what bugs are you talking about?
and also there are a lot of features that you never need to reimplement them like:
- Pausing queries
- Dependent queries
- Parallel queries
- Query retries
- etc
Features 2, and 3 already exist. If you need the other features, please open an RFC and we'll discuss whether it's relevant in the case of react-admin.
Someone already mentioned this an a issue in the past, but I see it as an option.
The MenuItemLink
or the Resource
could have a boolean
prop like filters-reset
that when a user enteres a list resource, the previous filters will not be considered. I know that the URL is the single source of truth, but this prop could trigger an URL param that could be used by ListContext
in order to ignore persisted filters of that resource when rendering the list.
I'm adding one possible breaking change: updating the format of the filters parameter passed to getList.
Currently, the filters are passed as
key: value
, e.g.:
{ filter: { name: "John Doe" } }
Which doesn't allow an operator. When developers want to use operators like greater than, includes, not equal, they currently have no standard way of doing so. We've got around this in demos by appending operators to the key name, but that's neither standard or explicit:
{ filter: { name_neq: "John Doe" } }
We should pass filters as an array of conditions, each condition being a field, an operator, and a value.
{ filter: [{ key: "name", operator: "NOT_EQUALS", value: "John Doe" }] }
dataProviders would then do what they want to convert that to their API syntax.
Cons: This would significantly increase the difficulty to build a dataProvider, and break all existing providers. Besides, not all backends support such operators, so basing a feature on the existence of these operators (like a date interval filter) would exclude some backends.
What do you think?
That looks a great idea! Currently in order to bypass this missing feature, our team creates pseudo sources keys, like source="gte#createDate
" and then they are parsed inside the logic of data provider in order to transform to something like createDate <= <value>
.
This feature could avoid this workaround and add some filter capabilities
I'm adding one possible breaking change: updating the format of the filters parameter passed to getList.
Currently, the filters are passed as
key: value
, e.g.:
{ filter: { name: "John Doe" } }
Which doesn't allow an operator. When developers want to use operators like greater than, includes, not equal, they currently have no standard way of doing so. We've got around this in demos by appending operators to the key name, but that's neither standard or explicit:
{ filter: { name_neq: "John Doe" } }
We should pass filters as an array of conditions, each condition being a field, an operator, and a value.
{ filter: [{ key: "name", operator: "NOT_EQUALS", value: "John Doe" }] }
dataProviders would then do what they want to convert that to their API syntax.
Cons: This would significantly increase the difficulty to build a dataProvider, and break all existing providers. Besides, not all backends support such operators, so basing a feature on the existence of these operators (like a date interval filter) would exclude some backends.
What do you think?
@fzaninotto I have faced the issue already and even handled it successfully. Making such a huge change with all the consequences seems a little bit too much to me. May I propose my solution:
Everything is managed on the backend when parsing filter keys.
And in this way everybody decides what operators he will support and how. Maybe not the neatest solution but at least not introducing BC.
Someone already mentioned this an a issue in the past, but I see it as an option.
The
MenuItemLink
or theResource
could have aboolean
prop likefilters-reset
that when a user enteres a list resource, the previous filters will not be considered. I know that the URL is the single source of truth, but this prop could trigger an URL param that could be used byListContext
in order to ignore persisted filters of that resource when rendering the list.
You don't need to wait for 4.0, or for any other version for that matter, to do this.
<Link to="/posts?filter=%7B%7D">Filter</Link>
Links to an unfiltered list of posts.
@fzaninotto is formik
the final choose or you can consider react-hook-form
?
react-hook-form
is still an option. We'll make the decision by comparing the feature list (and community) when we start the work.
I have an interesting one...
Feature request: Enable pinyin first letter search for autocomplete inputs.
Why: Chinese users often don't want to actually type the characters when searching they just want to type the first letter of each character in a string.
E.g. The simplified Chinese Characters for Hello is 你好 (pinyin: ni hao) . Chinese users want to find this by typing 'nh' in the autocomplete search bar.
Currently in my admin app we handle the search on the database side but it doesn't work for autocomplete inputs in ra due to the filterToQuery not supporting this.
See this package https://www.npmjs.com/package/pinyin-firstletter
Wondering how / if you would want to implement this. I think the main functionality we need is to be able to pass some function to the filterToQuery prop to transform the filtered data.
I would be happy to make a PR if it had chance of being merged.
@DataHippo93 You can already transform the user input to a custom query parameter, so this is already possible in react-admin. Please do not post "how to" questions in this thread.
Support multiple dashboard components, please.
@infilos Can you be a little more specific?
Ability to pass custom attributes to REST API data provider from components. This attribute could, for example, be used to define fields to be returned by REST API. This can be done by extending getXyzParams to include dataOptions attribute that is passed to data provider from standard react-admin components.
For example:
export interface GetListParams {
pagination: PaginationPayload;
sort: SortPayload;
filter: any;
dataOptions: any;
}
We're starting to think about the next major milestone for react-admin. It'll mostly be a cleanup release, removing all the deprecated features and the compatibility layers we put in place. It should also be the occasion to use the latest major version of our dependencies.
Breaking Changes
redux-saga
and saga-based side effects (#6684)connected-react-router
(#6704)react-final-form
withformik
orreact-hook-form
(#7087)<Show authenticated={false}>
) (#6921)useGetOne
(#6779)useGetList
(#6916)useGetMany
(#7006)useGetManyReference
(#7016)useCreate
(#7025)useUpdate
(#6891)useDelete
(#7035)useUpdateMany
(#7020)useDeleteMany
(#7035)<DataGridHeaderCell>
(#7065)Record
TypeScript name (which already exists in TypeScript) (#7078)basePath
(#7100)total
) (#7120)RichTextInput
with TipTap version (#7153)addField
) and render propsuseGetList
,useGetMatching
,useGetMany
anduseGetManyReference
consistent (some return a RecordMap, some return an array of records)sx
props in all ra-ui-materialui componentsThese items didn't make it into the release:
Automate integration of authProvider and dataProvider for credentialsNot crucialChange GraphQL Data Provider approach to avoid relying on runtime introspection (#6639)Will be done in a minor releaseUpdate BooleanInput signature (#4273)Use MUI Datagrid instead of our ownMaybe in a future versionWrite codemods to facilitate the upgradeWe won't break BC for another year or two after 4.0, so we'd better wait to incorporate the new major releases of our dependencies. This causes the following releases to be blockers:
useContext
(https://github.com/reactjs/rfcs/pull/119)Timeline
Work on v4 started in September 2021, and is expected to end in early 2022.
Note: Please don't post comments with feature requests that don't need a breaking change here. React-admin releases new features on a monthly basis, and doesn't need a major release for that. This discussion is only for backwards-incompatible changes.