-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Upgrade class components to functional components #9712
Comments
Recipes // TEMPLATE
function ComponentName(props, ref) {}
const ComponentName = React.forwardRef(
function ComponentName(props, ref) {}
);
ComponentName.propTypes = {};
Special cases
Situations where we would not want to migrate
How to use in monorepo
import * as FeatureFlags from '@carbon/feature-flags';
import { OverflowMenu as OverflowMenuNext } from './next/OverflowMenu';
import OverflowMenuClassic from './OverflowMenu';
export const OverflowMenu = FeatureFlags.enabled('enable-v11-release')
? OverflowMenuNext
: OverflowMenuClassic; |
example for how to handle function TestComponent({ example }) {
const [value, setValue] = useState(example);
useEffect(() => {
setValue(example);
}, [example]);
} becomes function TestComponent({ example }) {
const [value, setValue] = useState(example);
const [prevExample, setPrevExample] = useState(example);
if (example !== prevExample) {
setValue(example);
setPrevExample(example);
}
} |
Another thing to note on default vs named exports - the 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; |
We also need to add a new test file in the
|
Checklist
Questions
|
I can take over the task for the component:
|
Awesome! Thanks @motou we appreciate the contribution! I'll assign it to you. If you have any questions about the implementation, feel free to look at the other PRs we've opened so far, or ask questions here. 😄 |
the right file path is |
Moreover, I can work on the following components:
|
Priority of these can be divided into three sections: 1. Components that are likely to receive enhancement work post v112. Components that are commonly used
3. Everything else - Wrap these classes with a functional export
|
Looks like this can be marked as complete based on status of #10281 👍 |
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 aref
, and existing code that uses aref
would break. Similarly, usingReact.forwardRef
would produce a component where theref
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 usedReact.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/ToggleSmall/ToggleSmall.Skeleton.js(this component is deprecated)ToggleSmallSkeletonsrc/components/Toggle/Toggle.Skeleton.js(this component is deprecated)ToggleSkeletonsrc/components/Tooltip/Tooltip.jsTooltip(component is being replaced in another update)src/internal/FloatingMenu.jsFloatingMenu(component will be replaced by popover)src/components/ToolbarSearch/ToolbarSearch.jsToolbarSearchsrc/components/Toggle/Toggle.jsToggle(already covered in Toggle/next)src/components/SearchLayoutButton/SearchLayoutButton.jsSearchLayoutButton(component has been deprecated)src/internal/Selection.jsSelection(will be unnecessary after moving listbox components touseSelection
)src/components/ModalWrapper/ModalWrapper.jsModalWrapper(component is deprecated)src/components/ErrorBoundary/ErrorBoundary.jsErrorBoundary(has no hooks equivalent)src/components/DataTable/DataTable.jsDataTable(too big to migrate, may use hook format in the future)src/components/ContentSwitcher/ContentSwitcher.jsContentSwitcher(currently being updated separately)The text was updated successfully, but these errors were encountered: