question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Upgrade class components to functional components

See original GitHub issue

Why are we doing this?

According to the React team, switching a component from a class component to a functional component is technically a breaking change. This is because class components accept a ref that points to the class instance by default. There is no way to opt-out of this behavior. As a result, if we switched a component to a functional component it would no longer have a ref, and existing code that uses a ref would break. Similarly, using React.forwardRef would produce a component where the ref would no longer point to a class instance and code could similarly break.

We have moved some components over to the new format despite these situations. The rationale at the time was that we weren’t intending people to use these parts of a component (specifically class instance methods) and if teams were trying to use the ref to find a node in the document their code would work if we used React.forwardRef.

With v11, it seemed like a great opportunity to convert our remaining class components to the new functional component style with hooks.

Effort size legend ❇️ - sm ✴️ - md 🆘 - lg

Tasks

We would like to convert the following components to functional components that use hooks where appropriate:

  • ✴️ src/components/UIShell/SideNavMenu.js @joshblack
    • ✴️ SideNavMenu
  • ❇️ src/components/UIShell/HeaderNavigation.js @joshblack
    • ❇️ HeaderNavigation
  • ❇️ src/components/UIShell/HeaderMenu.js @joshblack
    • ❇️ HeaderMenu
  • src/components/ToggleSmall/ToggleSmall.Skeleton.js (this component is deprecated)
    • ToggleSmallSkeleton
  • src/components/Toggle/Toggle.Skeleton.js (this component is deprecated)
    • ToggleSkeleton
  • src/components/Tooltip/Tooltip.js
    • Tooltip (component is being replaced in another update)
  • ✴️ src/internal/ClickListener.js
    • ✴️ ClickListener
  • src/internal/FloatingMenu.js
    • FloatingMenu (component will be replaced by popover)
  • src/components/ToolbarSearch/ToolbarSearch.js
    • ToolbarSearch
  • src/components/Toggle/Toggle.js
    • Toggle (already covered in Toggle/next)
  • ❇️ src/components/TimePickerSelect/TimePickerSelect.js @sstrubberg
    • ❇️ TimePickerSelect
  • ✴️ src/components/TimePicker/TimePicker.js @sstrubberg
    • ✴️ TimePicker
  • ✴️ src/components/TileGroup/TileGroup.js @motou
  • src/components/Tile/Tile.js @sstrubberg
    • ❇️ Tile
    • ✴️ ClickableTile
    • 🆘 ExpandableTile (@abbeyhrt)
    • ❇️ TileAboveTheFoldContent
    • ❇️ TileBelowTheFoldContent
  • 🆘 src/components/Tabs/Tabs.js @jnm2377
    • 🆘 Tabs
  • ❇️ src/components/Tab/Tab.js @jnm2377
    • ❇️ Tab
  • 🆘 src/components/Slider/Slider.js @vpicone
  • ✴️ src/components/Search/Search.js @aledavila
  • src/components/SearchLayoutButton/SearchLayoutButton.js
    • SearchLayoutButton (component has been deprecated)
  • ✴️ src/components/RadioButtonGroup/RadioButtonGroup.js @jnm2377
    • ✴️ RadioButtonGroup
  • ❇️ src/components/RadioButton/RadioButton.js @jnm2377
    • ❇️ RadioButton
  • ✴️ src/components/ProgressIndicator/ProgressIndicator.js
    • ✴️ ProgressIndicator
    • #10020
  • 🆘 src/components/Pagination/Pagination.js
  • ✴️ src/components/OverflowMenuItem/OverflowMenuItem.js
    • ✴️ OverflowMenuItem
    • #10022
  • 🆘 src/components/OverflowMenu/OverflowMenu.js
  • 🆘 src/components/NumberInput/NumberInput.js @vpicone
  • 🆘 src/components/MultiSelect/FilterableMultiSelect.js
    • 🆘 FilterableMultiSelect
    • #10023
  • src/internal/Selection.js
    • Selection (will be unnecessary after moving listbox components to useSelection)
  • src/components/ModalWrapper/ModalWrapper.js
    • ModalWrapper (component is deprecated)
  • 🆘 src/components/Modal/Modal.js
  • ✴️ src/components/FileUploader/FileUploader.js
  • src/components/ErrorBoundary/ErrorBoundary.js
    • ErrorBoundary (has no hooks equivalent)
  • ❇️ src/components/DatePickerInput/DatePickerInput.js @jnm2377
    • ❇️ DatePickerInput
    • #10010
  • 🆘 src/components/DatePicker/DatePicker.js
  • ✴️ src/components/InlineCheckbox/InlineCheckbox.js
    • ✴️ InlineCheckbox
    • #10011
  • src/components/DataTable/DataTable.js
    • DataTable (too big to migrate, may use hook format in the future)
  • src/components/ContentSwitcher/ContentSwitcher.js
    • ContentSwitcher (currently being updated separately)
  • src/components/ComposedModal/ComposedModal.js
  • #10281

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:12 (12 by maintainers)

github_iconTop GitHub Comments

2reactions
tay1orjonescommented, Oct 4, 2021

Another thing to note on default vs named exports - the src/index.js is typically expecting a default export. So if you’re going to do a conditional export, it might be easiest to ensure it’s default exports all the way through the export chain.

For instance:

// MyFunComponent/next/MyFunComponent.js

export default function MyFunComponent({...props}) {
return (
    <div>{...props}</div>
  );
}

// MyFunComponent/index.js
import { default as MyFunComponentNext } from './next/MyFunComponent';
import { default as MyFunComponentClassic } from './MyFunComponent';

export default MyFunComponent = FeatureFlags.enabled('enable-v11-release') ? MyFunComponentNext : MyFunComponentClassic;
1reaction
motoucommented, Oct 26, 2021

I can take over the task for the component:

  • src/components/TileGroup/TileGroup.js ✴️ TileGroup
Read more comments on GitHub >

github_iconTop Results From Across the Web

How To Convert React Class Components to Functional ...
In this post, you'll explore five ways to convert React class components to functional components using React Hooks.
Read more >
How to convert Class Component into Functional ... - Medium
Converting to the functional component: · Removed the class keyword and directly exported our component · Removed use of constructor and super ...
Read more >
Converting class components to functional components (basic ...
Updating state. When we are updating our state in class components, we utilize React's setState function which has a slightly different API ...
Read more >
How to convert a React Class Component to a Function ...
Quick steps to convert to a function component · 1. Change the class to a function · 2. Remove the render method ·...
Read more >
Migrate a React Class Component to a Function ... - Egghead.io
Change the class keyword to function and remove the extends React. · Place the contents of the render() method in the function body...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found