Upgrade React apps by migrating class components to hooks, adopting React 18/19 concurrent features, running codemods, and adding TypeScript types.
数据来源:ClawHub。 在 ClawSkills 查看
选择你使用的 Agent
方法一:命令行安装(推荐)
推荐(无需提前安装 clawhub)
npx clawhub@latest --dir ~/.claude/skills install react-modernization或使用 clawhub CLI(需提前安装)
clawhub --dir ~/.claude/skills install react-modernization⚠️ 需要 Node.js 18+,没有 Node?请使用下方方法二直接下载 ZIP。 安装 Node.js →
方法二:手动下载安装(无需 Node)
下载 ZIP,解压后将文件夹放到以下路径,重启 Agent 即可:
安装路径
~/.claude/skills/react-modernization/💡解压后将文件夹放到上方路径,重启 Agent 即可生效
--- name: react-modernization model: reasoning ---
Upgrade React applications from class components to hooks, adopt concurrent features, and migrate between major versions.
Systematic patterns for modernizing React codebases:
react upgrade, class to hooks, useEffect, useState, react 18, react 19, concurrent, suspense, transition, codemod, migrate, modernize, functional component
npx clawhub@latest install react-modernization
---
| Change | Impact | Migration | |--------|--------|-----------| | New root API | Required | ReactDOM.render → createRoot | | Automatic batching | Behavior | State updates batch in async code now | | Strict Mode | Dev only | Effects fire twice (mount/unmount/mount) | | Suspense on server | Optional | Enable SSR streaming |
| Change | Impact | Migration | |--------|--------|-----------| | use() hook | New API | Read promises/context in render | | ref as prop | Simplified | No more forwardRef needed | | Context as provider | Simplified | not | | Async actions | New pattern | useActionState, useOptimistic |
---
// componentDidMount → useEffect with empty deps
useEffect(() => {
fetchData()
}, [])
// componentDidUpdate → useEffect with deps
useEffect(() => {
updateWhenIdChanges()
}, [id])
// componentWillUnmount → useEffect cleanup
useEffect(() => {
const subscription = subscribe()
return () => subscription.unsubscribe()
}, [])
// shouldComponentUpdate → React.memo
const Component = React.memo(({ data }) => <div>{data}</div>)
// getDerivedStateFromProps → useMemo
const derivedValue = useMemo(() => computeFrom(props), [props])
// BEFORE: Class with multiple state properties
class UserProfile extends React.Component {
state = { user: null, loading: true, error: null }
componentDidMount() {
fetchUser(this.props.id)
.then(user => this.setState({ user, loading: false }))
.catch(error => this.setState({ error, loading: false }))
}
componentDidUpdate(prevProps) {
if (prevProps.id !== this.props.id) {
this.setState({ loading: true })
fetchUser(this.props.id)
.then(user => this.setState({ user, loading: false }))
}
}
render() {
const { user, loading, error } = this.state
if (loading) return <Spinner />
if (error) return <Error message={error.message} />
return <Profile user={user} />
}
}
// AFTER: Custom hook + functional component
function useUser(id: string) {
const [user, setUser] = useState<User | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<Error | null>(null)
useEffect(() => {
let cancelled = false
setLoading(true)
fetchUser(id)
.then(data => {
if (!cancelled) {
setUser(data)
setLoading(false)
}
})
.catch(err => {
if (!cancelled) {
setError(err)
setLoading(false)
}
})
return () => { cancelled = true }
}, [id])
return { user, loading, error }
}
function UserProfile({ id }: { id: string }) {
const { user, loading, error } = useUser(id)
if (loading) return <Spinner />
if (error) return <Error message={error.message} />
return <Profile user={user} />
}
// BEFORE: Higher-Order Component
function withUser(Component) {
return function WithUser(props) {
const [user, setUser] = useState(null)
useEffect(() => { fetchUser().then(setUser) }, [])
return <Component {...props} user={user} />
}
}
const ProfileWithUser = withUser(Profile)
// AFTER: Custom hook (simpler, composable)
function useCurrentUser() {
const [user, setUser] = useState(null)
useEffect(() => { fetchUser().then(setUser) }, [])
return user
}
function Profile() {
const user = useCurrentUser()
return user ? <div>{user.name}</div> : null
}
---
// BEFORE: React 17
import ReactDOM from 'react-dom'
ReactDOM.render(<App />, document.getElementById('root'))
// AFTER: React 18+
import { createRoot } from 'react-dom/client'
const root = createRoot(document.getElementById('root')!)
root.render(<App />)
function SearchResults() {
const [query, setQuery] = useState('')
const [results, setResults] = useState([])
const [isPending, startTransition] = useTransition()
function handleChange(e: React.ChangeEvent<HTMLInputElement>) {
// Urgent: update input immediately
setQuery(e.target.value)
// Non-urgent: can be interrupted
startTransition(() => {
setResults(searchDatabase(e.target.value))
})
}
return (
<>
<input value={query} onChange={handleChange} />
{isPending ? <Spinner /> : <ResultsList data={results} />}
</>
)
}
// With React 19's use() hook
function ProfilePage({ userId }: { userId: string }) {
return (
<Suspense fallback={<ProfileSkeleton />}>
<ProfileDetails userId={userId} />
</Suspense>
)
}
function ProfileDetails({ userId }: { userId: string }) {
// use() suspends until promise resolves
const user = use(fetchUser(userId))
return <h1>{user.name}</h1>
}
// Read promises directly in render
function Comments({ commentsPromise }) {
const comments = use(commentsPromise)
return comments.map(c => <Comment key={c.id} {...c} />)
}
// Read context (simpler than useContext)
function ThemeButton() {
const theme = use(ThemeContext)
return <button className={theme}>Click</button>
}
// useActionState for form submissions
function UpdateName() {
const [error, submitAction, isPending] = useActionState(
async (previousState, formData) => {
const error = await updateName(formData.get('name'))
if (error) return error
redirect('/profile')
},
null
)
return (
<form action={submitAction}>
<input name="name" />
<button disabled={isPending}>Update</button>
{error && <p>{error}</p>}
</form>
)
}
---
# Update to new JSX transform (no React import needed)
npx codemod@latest react/19/replace-reactdom-render
# Update deprecated APIs
npx codemod@latest react/19/replace-string-ref
# Class to function components
npx codemod@latest react/19/replace-use-form-state
# Find class components
rg "class \w+ extends (React\.)?Component" --type tsx
# Find deprecated lifecycle methods
rg "componentWillMount|componentWillReceiveProps|componentWillUpdate" --type tsx
# Find ReactDOM.render (needs migration to createRoot)
rg "ReactDOM\.render" --type tsx
---
// Add types to functional components
interface ButtonProps {
onClick: () => void
children: React.ReactNode
variant?: 'primary' | 'secondary'
}
function Button({ onClick, children, variant = 'primary' }: ButtonProps) {
return (
<button onClick={onClick} className={variant}>
{children}
</button>
)
}
// Type event handlers
function Form() {
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
}
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
console.log(e.target.value)
}
return (
<form onSubmit={handleSubmit}>
<input onChange={handleChange} />
</form>
)
}
// Generic components
interface ListProps<T> {
items: T[]
renderItem: (item: T) => React.ReactNode
}
function List<T>({ items, renderItem }: ListProps<T>) {
return <>{items.map(renderItem)}</>
}
---
useStateuseEffectcreateRoot API---
// eslint-disable-next-line react-hooks/exhaustive-deps without understanding why安装 React Modernization 后,可以对 AI 说这些话来触发它
Help me get started with React Modernization
Explains what React Modernization does, walks through the setup, and runs a quick demo based on your current project
Use React Modernization to upgrade React apps by migrating class components to hooks, adopting...
Invokes React Modernization with the right parameters and returns the result directly in the conversation
What can I do with React Modernization in my developer & devops workflow?
Lists the top use cases for React Modernization, with example commands for each scenario
将技能文件夹放到 ~/.claude/skills/react-modernization/ 目录(个人级,所有项目可用),或 .claude/skills/react-modernization/(项目级)。重启 AI 客户端后,用 /react-modernization 主动调用,或让 AI 根据上下文自动发现并使用。
React Modernization 支持 Claude、Cursor、OpenClaw,可与这些 AI 平台无缝集成,扩展其能力。
React Modernization 可免费安装使用。请查阅仓库了解许可证信息。
Upgrade React apps by migrating class components to hooks, adopting React 18/19 concurrent features, running codemods, and adding TypeScript types.
React Modernization 属于「Developer & DevOps」分类,该分类的技能帮助 AI 智能体在此领域执行专业任务。
Automate my developer & devops tasks using React Modernization
Identifies repetitive steps in your workflow and sets up React Modernization to handle them automatically