feat: add class-to-functional-migration skill#12
Open
HassamAzam wants to merge 1 commit into
Open
Conversation
A behavior-preserving workflow for converting React class components to functional components with hooks. Covers state, lifecycle, refs, methods, derived values, HOCs, and forwardRef with concrete before/after examples, plus a correctness/performance/maintainability iteration pass and a common-pitfalls section.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new Claude skill that provides a structured, behavior-preserving workflow for migrating React class components to functional components using hooks, with emphasis on correctness pitfalls (deps, stale closures, cleanup) and iterative review passes.
Changes:
- Introduces a new skill document with a pre-migration audit checklist and a step-by-step conversion workflow.
- Adds a conversion map covering state, lifecycle methods, refs/instance fields, class methods, derived values, HOCs/context, and
forwardRef/imperative handles. - Documents common hook migration pitfalls (stale closures, missing deps, identity churn, derived state, cleanup) and expected outputs/constraints.
Comments suppressed due to low confidence (3)
Claude/skills/class-to-functional-migration/SKILL.md:196
- The guidance about dropping HOC wrappers is misleading: replacing an HOC (e.g.,
connect,withRouter) with hooks typically only requires changing the wrapped component itself; consumers that import/render the component usually do not need to be “rewritten as a hook”. Consider rephrasing to something like “drop the HOC wrapper once the component no longer relies on it, keeping the export shape the same to avoid breaking imports.”
Drop the HOC wrapper from the export once each consumer is rewritten as a hook.
Claude/skills/class-to-functional-migration/SKILL.md:280
- In the stale-closure example, the note “or use the functional setter form” doesn’t apply because the interval callback is only reading
count(logging), not updating state. Consider updating the guidance to an actually applicable fix (e.g., includecountin deps, or store the latest value in a ref, or use a stable event callback pattern) so readers don’t apply an ineffective pattern.
// FIX: include count, or use the functional setter form
useEffect(() => {
const id = setInterval(() => console.log(count), 1000);
return () => clearInterval(id);
}, [count]);
Claude/skills/class-to-functional-migration/SKILL.md:213
- The
useImperativeHandleexample omits the dependency array. For a migration guide that emphasizes stale-closure/identity issues, it would be clearer to show the third argument (e.g.,[]for a stable handle, or deps when the handle uses reactive values) to avoid recreating the handle each render and to align with common linting expectations.
useImperativeHandle(ref, () => ({
focus: () => inputRef.current.focus(),
}));
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| | `componentWillUnmount` | Cleanup function returned from `useEffect` | | ||
| | `getDerivedStateFromProps` | Compute during render, or sync via `useEffect` if needed | | ||
| | `shouldComponentUpdate` | Wrap export in `React.memo` with a custom comparator | | ||
| | `componentDidCatch` | Keep as a class `ErrorBoundary` — hooks cannot replace it| |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a new skill
Claude/skills/class-to-functional-migration/for converting React class components into functional components with hooks.Why
Class-to-hook conversion is one of the most common React refactors and is easy to get subtly wrong (stale closures, missing effect deps, identity churn, dropped cleanup). This skill gives the agent a strict, behavior-preserving workflow with concrete before/after code for every class construct so the conversion does not regress behavior.
What's in the skill
forwardRefusage before touching codeconnect,withRouter,withTranslation,withTheme/withStyles),forwardRef+useImperativeHandlecomponentDidCatch)useEffectfor derived state,useRefmisuse, missing cleanupQuality checklist
Claude/skills/class-to-functional-migration/SKILL.md)namefield follow kebab-casename,description,origin)SKILL.mdlimit (331 lines)