Early in the FOLIO project, we made the decision to use Redux Form to help construct forms with complex state. Redux Form has been a huge time-saver, since we don't have to roll a new state machine ourselves every time we build a new form. In the years since we adopted it, the thinking around form state in the React/Redux community has evolved. The Redux docs even indicate tools like Redux Form probably aren't needed: https://redux.js.org/faq/organizing-state#should-i-put-form-state-or-other-ui-state-in-my-store
Final Form is the direct successor to Redux Form. Final Form has significant performance gains because it doesn't dispatch actions to the Redux store on every key press. It doesn't even use Redux.
Additional benefits of Final Form we'd immediately benefit from:
- Modular pieces like final-form-calculate and final-form-focus
- Much smaller bundle footprint than Redux Form (or Formik)
- More mature API than Redux Form
Encourage the use of React Final Form instead of Redux Form.
ui-eholdings is already migrated over: https://github.com/folio-org/ui-eholdings/pull/680. Besides the performance benefits, I've much preferred the ergonomics of using React components instead of reduxForm() calls scattered around the component tree (which are really wrappers for redux connects). With Redux Form, it was much more difficult to adhere to one of the tenets of the route-based architecture defined in
STRIPES-589: Only route components found in src/routes communicate with the data layer or server.
There are cases where Redux Form is still the appropriate tool, like multi-page wizard forms, but they won't be the norm in FOLIO. We should remove the redux-form reducer from stripes-core, but modules that want to use redux-form for exceptional cases can still add that reducer themselves. ui-eholdings has an example of injecting a reducer.
In a post-Redux Form stripes ecosystem, the stripes-form library is no longer necessary. stripes-form provides two key pieces of functionality:
- When a user tries to submit a form and there's a validation error, the first error on the form receives focus. Final Form's solution: https://github.com/final-form/final-form-focus
- When a user has unsaved changes and attempts to leave the URL in question, pop up a modal asking them if they want to keep editing or abandon the form. This can be extracted into a standalone component a la <NavigationModal> in ui-eholdings: https://github.com/folio-org/ui-eholdings/blob/master/src/components/navigation-modal/navigation-modal.js
These are the items needed to unblock anyone from using React Final Form with the same features currently available from stripes-form.
- Switch stripes-components tests to use React Final Form instead of Redux Form. This would 100% eliminate stripes-components' dependency on redux. It also unlocks some simplification of the mountWithContext() helper.
- Expose a <NavigationModal> from stripes-core or stripes-components (which repo it belongs in is up for debate)
These are the next steps, where stripes-core and stripes-smart-components would no longer depend on stripes-form. Can be done in parallel with Tier Three tasks.
- Migrate stripes-core forms using redux-form to React Final Form.
- Migrate stripes-smart-components using stripes-form to instead use React Final Form with <NavigationModal> and final-form-focus. Remove stripes-smart-components dependency on stripes-form.
- Place deprecation warnings in stripes-form.
Migrating modules will take a while, but can be done on any timetable. At this stage redux-form and react-final-form can continue to be first-class citizens together.
- Identify platform-core modules using stripes-form. Refactor those instances to use React Final Form with <NavigationModal> and final-form-focus.
- Identify platform-complete modules using stripes-form. Refactor those instances to use React Final Form with <NavigationModal> and final-form-focus.
This is the stage where redux-form first-class support goes away, and modules that want to use it would need to add the reducer themselves.
- Remove redux-form reducer from stripes-core.
- Archive stripes-form.