Token导航 LogoToken导航TokenDH.com
研究检索需要联网clawhub未标认证来源可访问clear审计提醒

react-modernizationReact modernization 开发

Agent Skill

用于辅助前端页面、组件、样式和交互逻辑的开发与维护。它适合让 Agent 生成或审查 React、Next.js、Vue、Tailwind、CSS 等相关代码,整理组件结构,或定位布局和性能问题。使用时需要结合项目现有设计系统、路由和构建方式,避免只生成孤立片段;涉及页面改动时,应配合本地预览和构建检查确认视觉效果。

总安装

34,048

周安装

1,433

GitHub Stars

公开资料未说明

下载量

11,923
OpenClaw

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

MIT-0

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:react-modernization(React modernization 开发)
来源仓库:https://github.com/wpank/react-modernization
安装命令:
openclaw skills install react-modernization
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install react-modernization

简介

通过将类组件迁移到钩子、采用 React 18/19 并发功能、运行 codemod 和添加 TypeScript 类型来升级 React 应用程序。

SKILL.md

name
react-modernization
model
reasoning

React Modernization

Upgrade React applications from class components to hooks, adopt concurrent features, and migrate between major versions.

WHAT

Systematic patterns for modernizing React codebases:

  • Class-to-hooks migration with lifecycle method mappings
  • React 18/19 concurrent features adoption
  • TypeScript migration for React components
  • Automated codemods for bulk refactoring
  • Performance optimization with modern APIs

WHEN

  • Migrating class components to functional components with hooks
  • Upgrading React 16/17 apps to React 18/19
  • Adopting concurrent features (Suspense, transitions, use)
  • Converting HOCs and render props to custom hooks
  • Adding TypeScript to React projects

KEYWORDS

react upgrade, class to hooks, useEffect, useState, react 18, react 19, concurrent, suspense, transition, codemod, migrate, modernize, functional component

Installation

OpenClaw / Moltbot / Clawbot

npx clawhub@latest install react-modernization

Version Upgrade Paths

React 17 → 18 Breaking Changes

ChangeImpactMigration
New root APIRequiredReactDOM.rendercreateRoot
Automatic batchingBehaviorState updates batch in async code now
Strict ModeDev onlyEffects fire twice (mount/unmount/mount)
Suspense on serverOptionalEnable SSR streaming

React 18 → 19 Breaking Changes

ChangeImpactMigration
use() hookNew APIRead promises/context in render
ref as propSimplifiedNo more forwardRef needed
Context as providerSimplified<Context> not <Context.Provider>
Async actionsNew patternuseActionState, useOptimistic

Class to Hooks Migration

Lifecycle Method Mappings

// 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])

State Migration Pattern

// 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} />
}

HOC to Hook Migration

// 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
}

React 18+ Concurrent Features

New Root API (Required)

// 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 />)

useTransition for Non-Urgent Updates

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} />}
    </>
  )
}

Suspense for Data Fetching

// 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>
}

React 19: use() Hook

// 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>
}

React 19: Actions

// 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>
  )
}

Automated Codemods

Run Official React Codemods

# 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

Manual Search Patterns

# 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

TypeScript Migration

// 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)}</>
}

Migration Checklist

Pre-Migration

  • [ ] Upgrade dependencies incrementally
  • [ ] Review breaking changes in release notes
  • [ ] Set up comprehensive test coverage
  • [ ] Create feature branch

Class → Hooks

  • [ ] Start with leaf components (no children)
  • [ ] Convert state to useState
  • [ ] Convert lifecycle to useEffect
  • [ ] Extract shared logic to custom hooks
  • [ ] Convert HOCs to hooks where possible

React 18+ Upgrade

  • [ ] Update to createRoot API
  • [ ] Test with StrictMode double-invocation
  • [ ] Address hydration mismatches
  • [ ] Adopt Suspense boundaries where beneficial
  • [ ] Use transitions for expensive updates

Post-Migration

  • [ ] Run full test suite
  • [ ] Check for console warnings
  • [ ] Profile performance before/after
  • [ ] Document changes for team

NEVER

  • Skip testing after migration
  • Migrate multiple components in one commit
  • Ignore StrictMode warnings (they reveal bugs)
  • Use // eslint-disable-next-line react-hooks/exhaustive-deps without understanding why
  • Mix class and hooks in same component

适合场景

01

OpenClaw 用户查找和安装 Skill 时

02

用户想查找某类 Agent Skill 时

03

需要根据任务场景推荐可安装能力包时

04

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

OpenClaw

98.22%
按下载量换算11,711

安全审计

VirusTotal

可疑

ClawScan

通过

Static analysis

未展示

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills