Refactor class components to functional components
PLIP (Plone Improvement Proposal)
Responsible Persons
Proposer: Víctor Fernández de Alba (@sneridagh)
Seconder:
Abstract
Refactor all the possible components in Volto that still are class-based components. Convert them to functional components, whenever possible.
Motivation
Volto still have a number of core components that are React class-based components. This prevents the use of hooks in them, and newest DX on them.
The idea is also while moving to them, use hooks to abstract the functionality present in Redux and in data fetching so in a near future we can easily switch using the hooks to use other props provider.
Assumptions
No assumptions.
Proposal & Implementation
Refactor should be done carefully and providing Cypress (acceptance) tests where they do not exist. The lifecycle of the components should be preserved while watching out for edge cases and UX problems.
Deliverables
It should be delivered all at once, as a major breaking change. Ideally, we won't change the contract of any of the components, so no new props passed down, no return anything to the tree that we were not returning before, unless it's justified.
If the contract has to be broken, then it must be properly documented and exposed in the upgrade guide.
The refactored components. Here there is a preliminary list, subject to change:
- [x] https://github.com/plone/volto/pull/4875 (src/components/theme/Comments/CommentEditModal.jsx)
- [x] https://github.com/plone/volto/pull/4874 (src/components/theme/Comments/Comments.jsx)
- [x] https://github.com/plone/volto/pull/4945 (src/components/theme/ContactForm/ContactForm.jsx)
- [x] https://github.com/plone/volto/pull/4876 (src/components/theme/Navigation/Navigation.jsx)
- [x] https://github.com/plone/volto/pull/4860 (src/components/theme/Logout/Logout.jsx)
- [x] https://github.com/plone/volto/pull/4873 (src/components/theme/Search/SearchTags.jsx)
- [x] https://github.com/plone/volto/pull/4938 (src/components/theme/PasswordReset/RequestPasswordReset.jsx)
- [x] https://github.com/plone/volto/pull/4866 (src/components/theme/View/LinkView.jsx)
- [x] https://github.com/plone/volto/pull/4864 (src/components/theme/SearchWidget/SearchWidget.jsx)
- [x] https://github.com/plone/volto/pull/4845 (src/components/theme/Anontools/Anontools.jsx)
- [x] https://github.com/plone/volto/pull/4933 (src/components/theme/Login/Login.jsx)
- [x] https://github.com/plone/volto/pull/4858, https://github.com/plone/volto/pull/5048, and https://github.com/plone/volto/pull/5049 (src/components/theme/Breadcrumbs/Breadcrumbs.jsx)
- [ ] src/components/theme/Search/Search.jsx
- [ ] src/components/theme/Sitemap/Sitemap.jsx
- [ ] src/components/theme/PasswordReset/PasswordReset.jsx
- [ ] src/components/theme/Header/Header.jsx
- [ ] src/components/manage/Blocks/HTML/Edit.jsx
- [ ] src/components/manage/Blocks/Table/Edit.jsx
- [ ] src/components/manage/Blocks/HeroImageLeft/Edit.jsx
- [ ] src/components/manage/Blocks/Block/Edit.jsx
- [ ] src/components/manage/Blocks/Text/Edit.jsx
- [x] https://github.com/plone/volto/pull/4861 (src/components/theme/Register/Register.jsx)
- [x] https://github.com/plone/volto/pull/4877 (src/components/theme/View/AlbumView.jsx)
- [x] https://github.com/plone/volto/pull/4959 and https://github.com/plone/volto/pull/6206 - src/components/manage/Blocks/LeadImage/Edit.jsx
- [x] https://github.com/plone/volto/pull/4960 (src/components/manage/Blocks/Video/Edit.jsx)
- [x] https://github.com/plone/volto/pull/4958 (src/components/manage/Blocks/Maps/Edit.jsx)
- [x] https://github.com/plone/volto/pull/4961 and https://github.com/plone/volto/pull/6167 (src/components/manage/Blocks/ToC/Edit.jsx)
- [ ] https://github.com/plone/volto/pull/4957 (src/components/manage/Blocks/Image/Edit.jsx)
- [x] #4970 src/components/manage/Contents/ContentsTagsModal.jsx
- [x] https://github.com/plone/volto/pull/5570 - src/components/manage/Blocks/Search/widgets/SelectMetadataField.jsx
- [x] #4965 src/components/manage/Sidebar/Sidebar.jsx
- [ ] https://github.com/plone/volto/pull/6182 - src/components/manage/Blocks/Table/Cell.jsx (moved to volto-slate?)
- [x] #4969 src/components/manage/Contents/ContentsWorkflowModal.jsx
- [x] #4968 src/components/manage/Contents/ContentsPropertiesModal.jsx
- [x] #4971 src/components/manage/Contents/ContentsRenameModal.jsx
- [x] https://github.com/plone/volto/pull/5047 and https://github.com/plone/volto/pull/6178 - src/components/manage/Contents/ContentsUploadModal.jsx
- [x] https://github.com/plone/volto/pull/5046 and https://github.com/plone/volto/pull/6177 - src/components/manage/Preferences/PersonalInformation.jsx
- [x] https://github.com/plone/volto/pull/5045 - src/components/manage/Preferences/PersonalPreferences.jsx
- [x] https://github.com/plone/volto/pull/5044 - src/components/manage/Preferences/ChangePassword.jsx
- [ ] src/components/manage/Form/ModalForm.jsx
- [ ] src/components/manage/AnchorPlugin/components/LinkButton/index.jsx
- [ ] src/components/manage/AnchorPlugin/components/LinkButton/AddLinkForm.jsx
- [x] https://github.com/plone/volto/pull/4926 (src/components/manage/Messages/Messages.jsx)
- [ ] https://github.com/plone/volto/pull/4918 (src/components/manage/Sharing/Sharing.jsx)
- [ ] src/components/manage/Controlpanels/ContentType.jsx
- [ ] src/components/manage/Controlpanels/Controlpanels.jsx
- [ ] src/components/manage/Controlpanels/ContentTypes.jsx
- [x] https://github.com/plone/volto/pull/4985 -src/components/manage/Controlpanels/Aliases.jsx
- [x] https://github.com/plone/volto/pull/4986 - src/components/manage/Controlpanels/DatabaseInformation.jsx
- [x] https://github.com/plone/volto/pull/5048 - src/components/manage/Controlpanels/UndoControlpanel.jsx
- [ ] src/components/manage/Controlpanels/Groups/GroupsControlpanel.jsx
- [x] https://github.com/plone/volto/pull/4993 - src/components/manage/Controlpanels/Groups/RenderGroups.jsx
- [x] src/components/manage/Controlpanels/Users/RenderUsers.jsx
- [x] https://github.com/plone/volto/pull/7450 - src/components/manage/Controlpanels/Users/UsersControlpanel.jsx
- [ ] https://github.com/plone/volto/pull/6208 - src/components/manage/Controlpanels/ContentTypeSchema.jsx
- [ ] https://github.com/plone/volto/pull/6210 -src/components/manage/Controlpanels/Controlpanel.jsx
- [x] https://github.com/plone/volto/pull/4995 - src/components/manage/Controlpanels/AddonsControlpanel.jsx
- [ ] https://github.com/plone/volto/pull/6199 - src/components/manage/Controlpanels/ModerateComments.jsx
- [x] https://github.com/plone/volto/pull/4890 (src/components/manage/Delete/Delete.jsx)
- [x] https://github.com/plone/volto/pull/4955 (src/components/manage/Toolbar/More.jsx)
- [x] https://github.com/plone/volto/pull/4954 (src/components/manage/Toolbar/PersonalTools.jsx)
- [ ] https://github.com/plone/volto/pull/4956 (src/components/manage/Toolbar/Toolbar.jsx)
- [ ] src/components/manage/Diff/Diff.jsx
- [x] https://github.com/plone/volto/pull/4902 (src/components/manage/Workflow/Workflow.jsx)
- [ ] src/components/manage/History/History.jsx
- [x] https://github.com/plone/volto/pull/4939 (src/components/manage/Actions/Actions.jsx)
- [x] https://github.com/plone/volto/pull/5066 and https://github.com/plone/volto/pull/6204 - src/components/manage/Display/Display.jsx
- [ ] https://github.com/plone/volto/pull/6196 - src/components/manage/Aliases/Aliases.jsx
- [ ] https://github.com/plone/volto/pull/5094 - src/components/manage/Widgets/SelectWidget.jsx
- [x] https://github.com/plone/volto/pull/5093 - src/components/manage/Widgets/ReferenceWidget.jsx
- [x] https://github.com/plone/volto/pull/7672
src/components/manage/Widgets/FormFieldWrapper.jsx - [x] #6027 src/components/manage/Widgets/IdWidget.jsx
- [ ] src/components/manage/Widgets/QueryWidget.jsx
- [ ] src/components/manage/Widgets/WysiwygWidget.jsx
- [ ] src/components/manage/Widgets/ArrayWidget.jsx
- [ ] https://github.com/plone/volto/pull/6215 - src/components/manage/Widgets/ObjectBrowserWidget.jsx
- [ ] src/components/manage/Widgets/RecurrenceWidget/RecurrenceWidget.jsx
- [ ] src/components/manage/Widgets/RecurrenceWidget/WeekdayOfTheMonthIndexField.jsx
- [x] https://github.com/plone/volto/pull/6213 - src/components/manage/Widgets/DatetimeWidget.jsx
- [ ] src/components/manage/Widgets/TokenWidget.jsx
- [ ] src/components/manage/Widgets/SchemaWidget.jsx
- [ ] https://github.com/plone/volto/pull/6212 - src/components/manage/Widgets/SelectAutoComplete.jsx
- [x] #6020 src/components/manage/Widgets/TextWidget.jsx
Complex / Optional:
- [ ] src/components/theme/View/View.jsx
- [ ] src/components/theme/App/App.jsx
- [ ] src/components/manage/Edit/Edit.jsx
- [ ] src/components/manage/Add/Add.jsx
- [ ] src/components/manage/Form/Form.jsx
- [ ] src/components/manage/Contents/Contents.jsx
- [ ] src/components/manage/Controlpanels/ContentTypeLayout.jsx
- [ ] src/components/manage/Sidebar/ObjectBrowserBody.jsx
- [ ] src/helpers/Html/Html.jsx
- [ ] src/helpers/BodyClass/BodyClass.jsx
Risks
The lifecycle of a component could easily be changed if the refactor is not done carefully and giving attention to details, that's why we should provide acceptance tests and heavy QA should be done while doing it.
Participants
- Víctor Fernández de Alba (@sneridagh)
- Tisha Soumya (@Tishasoumya-02)
This PLIP was part of the GSOC 2023 project assigned to Tisha Soumya (@Tishasoumya-02). Its scope proved to be too large for a single GSoC effort, and some components were left unfactored. She is available to review or approve pull requests for this PLIP.
⚠️ IMPORTANT ⚠️
The above list may be out of date. Do not duplicate effort. Search the issues and pull requests for existing work.
Read and follow First-time contributors, especially Things not to do, Contributing to Plone, and Contributing to Volto.
If your instructor gave you a class assignment to work on Volto or open source software, or you otherwise have no commitment to use and develop Plone or Volto, then you are not a contributor.
Pull requests that fail to comply with these contributing guidelines may be closed without explanation.
To all GSOC aspirants: https://community.plone.org/t/recommendations-for-gsoc-aspirants/16301/3
/cc @sudhanshu1309
@sneridagh what Plone version is this feature planned for?
@tisto This is an ongoing effort. Tisha worked on this during her GSOC. The reach was too broad, so we had to cut it down. This can be presented again in the next GSOC for continuation of the work.
The ones reviewed and merged (during 17 alpha phase) were released in Volto 17.
In the meanwhile, there are still some PRs opened (one per component). These are merged in alpha stages, because they are considered breaking. AFAIK, the project is stalled right now.