{
  "schemaVersion": "1.0",
  "item": {
    "slug": "react-modernization",
    "name": "React Modernization",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/wpank/react-modernization",
    "canonicalUrl": "https://clawhub.ai/wpank/react-modernization",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/react-modernization",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=react-modernization",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "SKILL.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "slug": "react-modernization",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-05-07T23:13:10.690Z",
      "expiresAt": "2026-05-14T23:13:10.690Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=react-modernization",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=react-modernization",
        "contentDisposition": "attachment; filename=\"react-modernization-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null,
        "slug": "react-modernization"
      },
      "scope": "item",
      "summary": "Item download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this item.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/react-modernization"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/react-modernization",
    "agentPageUrl": "https://openagent3.xyz/skills/react-modernization/agent",
    "manifestUrl": "https://openagent3.xyz/skills/react-modernization/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/react-modernization/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "React Modernization",
        "body": "Upgrade React applications from class components to hooks, adopt concurrent features, and migrate between major versions."
      },
      {
        "title": "WHAT",
        "body": "Systematic patterns for modernizing React codebases:\n\nClass-to-hooks migration with lifecycle method mappings\nReact 18/19 concurrent features adoption\nTypeScript migration for React components\nAutomated codemods for bulk refactoring\nPerformance optimization with modern APIs"
      },
      {
        "title": "WHEN",
        "body": "Migrating class components to functional components with hooks\nUpgrading React 16/17 apps to React 18/19\nAdopting concurrent features (Suspense, transitions, use)\nConverting HOCs and render props to custom hooks\nAdding TypeScript to React projects"
      },
      {
        "title": "KEYWORDS",
        "body": "react upgrade, class to hooks, useEffect, useState, react 18, react 19, concurrent, suspense, transition, codemod, migrate, modernize, functional component"
      },
      {
        "title": "OpenClaw / Moltbot / Clawbot",
        "body": "npx clawhub@latest install react-modernization"
      },
      {
        "title": "React 17 → 18 Breaking Changes",
        "body": "ChangeImpactMigrationNew root APIRequiredReactDOM.render → createRootAutomatic batchingBehaviorState updates batch in async code nowStrict ModeDev onlyEffects fire twice (mount/unmount/mount)Suspense on serverOptionalEnable SSR streaming"
      },
      {
        "title": "React 18 → 19 Breaking Changes",
        "body": "ChangeImpactMigrationuse() hookNew APIRead promises/context in renderref as propSimplifiedNo more forwardRef neededContext as providerSimplified<Context> not <Context.Provider>Async actionsNew patternuseActionState, useOptimistic"
      },
      {
        "title": "Lifecycle Method Mappings",
        "body": "// componentDidMount → useEffect with empty deps\nuseEffect(() => {\n  fetchData()\n}, [])\n\n// componentDidUpdate → useEffect with deps\nuseEffect(() => {\n  updateWhenIdChanges()\n}, [id])\n\n// componentWillUnmount → useEffect cleanup\nuseEffect(() => {\n  const subscription = subscribe()\n  return () => subscription.unsubscribe()\n}, [])\n\n// shouldComponentUpdate → React.memo\nconst Component = React.memo(({ data }) => <div>{data}</div>)\n\n// getDerivedStateFromProps → useMemo\nconst derivedValue = useMemo(() => computeFrom(props), [props])"
      },
      {
        "title": "State Migration Pattern",
        "body": "// BEFORE: Class with multiple state properties\nclass UserProfile extends React.Component {\n  state = { user: null, loading: true, error: null }\n  \n  componentDidMount() {\n    fetchUser(this.props.id)\n      .then(user => this.setState({ user, loading: false }))\n      .catch(error => this.setState({ error, loading: false }))\n  }\n  \n  componentDidUpdate(prevProps) {\n    if (prevProps.id !== this.props.id) {\n      this.setState({ loading: true })\n      fetchUser(this.props.id)\n        .then(user => this.setState({ user, loading: false }))\n    }\n  }\n  \n  render() {\n    const { user, loading, error } = this.state\n    if (loading) return <Spinner />\n    if (error) return <Error message={error.message} />\n    return <Profile user={user} />\n  }\n}\n\n// AFTER: Custom hook + functional component\nfunction useUser(id: string) {\n  const [user, setUser] = useState<User | null>(null)\n  const [loading, setLoading] = useState(true)\n  const [error, setError] = useState<Error | null>(null)\n\n  useEffect(() => {\n    let cancelled = false\n    setLoading(true)\n    \n    fetchUser(id)\n      .then(data => {\n        if (!cancelled) {\n          setUser(data)\n          setLoading(false)\n        }\n      })\n      .catch(err => {\n        if (!cancelled) {\n          setError(err)\n          setLoading(false)\n        }\n      })\n\n    return () => { cancelled = true }\n  }, [id])\n\n  return { user, loading, error }\n}\n\nfunction UserProfile({ id }: { id: string }) {\n  const { user, loading, error } = useUser(id)\n  \n  if (loading) return <Spinner />\n  if (error) return <Error message={error.message} />\n  return <Profile user={user} />\n}"
      },
      {
        "title": "HOC to Hook Migration",
        "body": "// BEFORE: Higher-Order Component\nfunction withUser(Component) {\n  return function WithUser(props) {\n    const [user, setUser] = useState(null)\n    useEffect(() => { fetchUser().then(setUser) }, [])\n    return <Component {...props} user={user} />\n  }\n}\n\nconst ProfileWithUser = withUser(Profile)\n\n// AFTER: Custom hook (simpler, composable)\nfunction useCurrentUser() {\n  const [user, setUser] = useState(null)\n  useEffect(() => { fetchUser().then(setUser) }, [])\n  return user\n}\n\nfunction Profile() {\n  const user = useCurrentUser()\n  return user ? <div>{user.name}</div> : null\n}"
      },
      {
        "title": "New Root API (Required)",
        "body": "// BEFORE: React 17\nimport ReactDOM from 'react-dom'\nReactDOM.render(<App />, document.getElementById('root'))\n\n// AFTER: React 18+\nimport { createRoot } from 'react-dom/client'\nconst root = createRoot(document.getElementById('root')!)\nroot.render(<App />)"
      },
      {
        "title": "useTransition for Non-Urgent Updates",
        "body": "function SearchResults() {\n  const [query, setQuery] = useState('')\n  const [results, setResults] = useState([])\n  const [isPending, startTransition] = useTransition()\n\n  function handleChange(e: React.ChangeEvent<HTMLInputElement>) {\n    // Urgent: update input immediately\n    setQuery(e.target.value)\n    \n    // Non-urgent: can be interrupted\n    startTransition(() => {\n      setResults(searchDatabase(e.target.value))\n    })\n  }\n\n  return (\n    <>\n      <input value={query} onChange={handleChange} />\n      {isPending ? <Spinner /> : <ResultsList data={results} />}\n    </>\n  )\n}"
      },
      {
        "title": "Suspense for Data Fetching",
        "body": "// With React 19's use() hook\nfunction ProfilePage({ userId }: { userId: string }) {\n  return (\n    <Suspense fallback={<ProfileSkeleton />}>\n      <ProfileDetails userId={userId} />\n    </Suspense>\n  )\n}\n\nfunction ProfileDetails({ userId }: { userId: string }) {\n  // use() suspends until promise resolves\n  const user = use(fetchUser(userId))\n  return <h1>{user.name}</h1>\n}"
      },
      {
        "title": "React 19: use() Hook",
        "body": "// Read promises directly in render\nfunction Comments({ commentsPromise }) {\n  const comments = use(commentsPromise)\n  return comments.map(c => <Comment key={c.id} {...c} />)\n}\n\n// Read context (simpler than useContext)\nfunction ThemeButton() {\n  const theme = use(ThemeContext)\n  return <button className={theme}>Click</button>\n}"
      },
      {
        "title": "React 19: Actions",
        "body": "// useActionState for form submissions\nfunction UpdateName() {\n  const [error, submitAction, isPending] = useActionState(\n    async (previousState, formData) => {\n      const error = await updateName(formData.get('name'))\n      if (error) return error\n      redirect('/profile')\n    },\n    null\n  )\n\n  return (\n    <form action={submitAction}>\n      <input name=\"name\" />\n      <button disabled={isPending}>Update</button>\n      {error && <p>{error}</p>}\n    </form>\n  )\n}"
      },
      {
        "title": "Run Official React Codemods",
        "body": "# Update to new JSX transform (no React import needed)\nnpx codemod@latest react/19/replace-reactdom-render\n\n# Update deprecated APIs\nnpx codemod@latest react/19/replace-string-ref\n\n# Class to function components\nnpx codemod@latest react/19/replace-use-form-state"
      },
      {
        "title": "Manual Search Patterns",
        "body": "# Find class components\nrg \"class \\w+ extends (React\\.)?Component\" --type tsx\n\n# Find deprecated lifecycle methods\nrg \"componentWillMount|componentWillReceiveProps|componentWillUpdate\" --type tsx\n\n# Find ReactDOM.render (needs migration to createRoot)\nrg \"ReactDOM\\.render\" --type tsx"
      },
      {
        "title": "TypeScript Migration",
        "body": "// Add types to functional components\ninterface ButtonProps {\n  onClick: () => void\n  children: React.ReactNode\n  variant?: 'primary' | 'secondary'\n}\n\nfunction Button({ onClick, children, variant = 'primary' }: ButtonProps) {\n  return (\n    <button onClick={onClick} className={variant}>\n      {children}\n    </button>\n  )\n}\n\n// Type event handlers\nfunction Form() {\n  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n    e.preventDefault()\n  }\n  \n  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    console.log(e.target.value)\n  }\n\n  return (\n    <form onSubmit={handleSubmit}>\n      <input onChange={handleChange} />\n    </form>\n  )\n}\n\n// Generic components\ninterface ListProps<T> {\n  items: T[]\n  renderItem: (item: T) => React.ReactNode\n}\n\nfunction List<T>({ items, renderItem }: ListProps<T>) {\n  return <>{items.map(renderItem)}</>\n}"
      },
      {
        "title": "Pre-Migration",
        "body": "Upgrade dependencies incrementally\n Review breaking changes in release notes\n Set up comprehensive test coverage\n Create feature branch"
      },
      {
        "title": "Class → Hooks",
        "body": "Start with leaf components (no children)\n Convert state to useState\n Convert lifecycle to useEffect\n Extract shared logic to custom hooks\n Convert HOCs to hooks where possible"
      },
      {
        "title": "React 18+ Upgrade",
        "body": "Update to createRoot API\n Test with StrictMode double-invocation\n Address hydration mismatches\n Adopt Suspense boundaries where beneficial\n Use transitions for expensive updates"
      },
      {
        "title": "Post-Migration",
        "body": "Run full test suite\n Check for console warnings\n Profile performance before/after\n Document changes for team"
      },
      {
        "title": "NEVER",
        "body": "Skip testing after migration\nMigrate multiple components in one commit\nIgnore StrictMode warnings (they reveal bugs)\nUse // eslint-disable-next-line react-hooks/exhaustive-deps without understanding why\nMix class and hooks in same component"
      }
    ],
    "body": "React Modernization\n\nUpgrade React applications from class components to hooks, adopt concurrent features, and migrate between major versions.\n\nWHAT\n\nSystematic patterns for modernizing React codebases:\n\nClass-to-hooks migration with lifecycle method mappings\nReact 18/19 concurrent features adoption\nTypeScript migration for React components\nAutomated codemods for bulk refactoring\nPerformance optimization with modern APIs\nWHEN\nMigrating class components to functional components with hooks\nUpgrading React 16/17 apps to React 18/19\nAdopting concurrent features (Suspense, transitions, use)\nConverting HOCs and render props to custom hooks\nAdding TypeScript to React projects\nKEYWORDS\n\nreact upgrade, class to hooks, useEffect, useState, react 18, react 19, concurrent, suspense, transition, codemod, migrate, modernize, functional component\n\nInstallation\nOpenClaw / Moltbot / Clawbot\nnpx clawhub@latest install react-modernization\n\nVersion Upgrade Paths\nReact 17 → 18 Breaking Changes\nChange\tImpact\tMigration\nNew root API\tRequired\tReactDOM.render → createRoot\nAutomatic batching\tBehavior\tState updates batch in async code now\nStrict Mode\tDev only\tEffects fire twice (mount/unmount/mount)\nSuspense on server\tOptional\tEnable SSR streaming\nReact 18 → 19 Breaking Changes\nChange\tImpact\tMigration\nuse() hook\tNew API\tRead promises/context in render\nref as prop\tSimplified\tNo more forwardRef needed\nContext as provider\tSimplified\t<Context> not <Context.Provider>\nAsync actions\tNew pattern\tuseActionState, useOptimistic\nClass to Hooks Migration\nLifecycle Method Mappings\n// componentDidMount → useEffect with empty deps\nuseEffect(() => {\n  fetchData()\n}, [])\n\n// componentDidUpdate → useEffect with deps\nuseEffect(() => {\n  updateWhenIdChanges()\n}, [id])\n\n// componentWillUnmount → useEffect cleanup\nuseEffect(() => {\n  const subscription = subscribe()\n  return () => subscription.unsubscribe()\n}, [])\n\n// shouldComponentUpdate → React.memo\nconst Component = React.memo(({ data }) => <div>{data}</div>)\n\n// getDerivedStateFromProps → useMemo\nconst derivedValue = useMemo(() => computeFrom(props), [props])\n\nState Migration Pattern\n// BEFORE: Class with multiple state properties\nclass UserProfile extends React.Component {\n  state = { user: null, loading: true, error: null }\n  \n  componentDidMount() {\n    fetchUser(this.props.id)\n      .then(user => this.setState({ user, loading: false }))\n      .catch(error => this.setState({ error, loading: false }))\n  }\n  \n  componentDidUpdate(prevProps) {\n    if (prevProps.id !== this.props.id) {\n      this.setState({ loading: true })\n      fetchUser(this.props.id)\n        .then(user => this.setState({ user, loading: false }))\n    }\n  }\n  \n  render() {\n    const { user, loading, error } = this.state\n    if (loading) return <Spinner />\n    if (error) return <Error message={error.message} />\n    return <Profile user={user} />\n  }\n}\n\n// AFTER: Custom hook + functional component\nfunction useUser(id: string) {\n  const [user, setUser] = useState<User | null>(null)\n  const [loading, setLoading] = useState(true)\n  const [error, setError] = useState<Error | null>(null)\n\n  useEffect(() => {\n    let cancelled = false\n    setLoading(true)\n    \n    fetchUser(id)\n      .then(data => {\n        if (!cancelled) {\n          setUser(data)\n          setLoading(false)\n        }\n      })\n      .catch(err => {\n        if (!cancelled) {\n          setError(err)\n          setLoading(false)\n        }\n      })\n\n    return () => { cancelled = true }\n  }, [id])\n\n  return { user, loading, error }\n}\n\nfunction UserProfile({ id }: { id: string }) {\n  const { user, loading, error } = useUser(id)\n  \n  if (loading) return <Spinner />\n  if (error) return <Error message={error.message} />\n  return <Profile user={user} />\n}\n\nHOC to Hook Migration\n// BEFORE: Higher-Order Component\nfunction withUser(Component) {\n  return function WithUser(props) {\n    const [user, setUser] = useState(null)\n    useEffect(() => { fetchUser().then(setUser) }, [])\n    return <Component {...props} user={user} />\n  }\n}\n\nconst ProfileWithUser = withUser(Profile)\n\n// AFTER: Custom hook (simpler, composable)\nfunction useCurrentUser() {\n  const [user, setUser] = useState(null)\n  useEffect(() => { fetchUser().then(setUser) }, [])\n  return user\n}\n\nfunction Profile() {\n  const user = useCurrentUser()\n  return user ? <div>{user.name}</div> : null\n}\n\nReact 18+ Concurrent Features\nNew Root API (Required)\n// BEFORE: React 17\nimport ReactDOM from 'react-dom'\nReactDOM.render(<App />, document.getElementById('root'))\n\n// AFTER: React 18+\nimport { createRoot } from 'react-dom/client'\nconst root = createRoot(document.getElementById('root')!)\nroot.render(<App />)\n\nuseTransition for Non-Urgent Updates\nfunction SearchResults() {\n  const [query, setQuery] = useState('')\n  const [results, setResults] = useState([])\n  const [isPending, startTransition] = useTransition()\n\n  function handleChange(e: React.ChangeEvent<HTMLInputElement>) {\n    // Urgent: update input immediately\n    setQuery(e.target.value)\n    \n    // Non-urgent: can be interrupted\n    startTransition(() => {\n      setResults(searchDatabase(e.target.value))\n    })\n  }\n\n  return (\n    <>\n      <input value={query} onChange={handleChange} />\n      {isPending ? <Spinner /> : <ResultsList data={results} />}\n    </>\n  )\n}\n\nSuspense for Data Fetching\n// With React 19's use() hook\nfunction ProfilePage({ userId }: { userId: string }) {\n  return (\n    <Suspense fallback={<ProfileSkeleton />}>\n      <ProfileDetails userId={userId} />\n    </Suspense>\n  )\n}\n\nfunction ProfileDetails({ userId }: { userId: string }) {\n  // use() suspends until promise resolves\n  const user = use(fetchUser(userId))\n  return <h1>{user.name}</h1>\n}\n\nReact 19: use() Hook\n// Read promises directly in render\nfunction Comments({ commentsPromise }) {\n  const comments = use(commentsPromise)\n  return comments.map(c => <Comment key={c.id} {...c} />)\n}\n\n// Read context (simpler than useContext)\nfunction ThemeButton() {\n  const theme = use(ThemeContext)\n  return <button className={theme}>Click</button>\n}\n\nReact 19: Actions\n// useActionState for form submissions\nfunction UpdateName() {\n  const [error, submitAction, isPending] = useActionState(\n    async (previousState, formData) => {\n      const error = await updateName(formData.get('name'))\n      if (error) return error\n      redirect('/profile')\n    },\n    null\n  )\n\n  return (\n    <form action={submitAction}>\n      <input name=\"name\" />\n      <button disabled={isPending}>Update</button>\n      {error && <p>{error}</p>}\n    </form>\n  )\n}\n\nAutomated Codemods\nRun Official React Codemods\n# Update to new JSX transform (no React import needed)\nnpx codemod@latest react/19/replace-reactdom-render\n\n# Update deprecated APIs\nnpx codemod@latest react/19/replace-string-ref\n\n# Class to function components\nnpx codemod@latest react/19/replace-use-form-state\n\nManual Search Patterns\n# Find class components\nrg \"class \\w+ extends (React\\.)?Component\" --type tsx\n\n# Find deprecated lifecycle methods\nrg \"componentWillMount|componentWillReceiveProps|componentWillUpdate\" --type tsx\n\n# Find ReactDOM.render (needs migration to createRoot)\nrg \"ReactDOM\\.render\" --type tsx\n\nTypeScript Migration\n// Add types to functional components\ninterface ButtonProps {\n  onClick: () => void\n  children: React.ReactNode\n  variant?: 'primary' | 'secondary'\n}\n\nfunction Button({ onClick, children, variant = 'primary' }: ButtonProps) {\n  return (\n    <button onClick={onClick} className={variant}>\n      {children}\n    </button>\n  )\n}\n\n// Type event handlers\nfunction Form() {\n  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {\n    e.preventDefault()\n  }\n  \n  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    console.log(e.target.value)\n  }\n\n  return (\n    <form onSubmit={handleSubmit}>\n      <input onChange={handleChange} />\n    </form>\n  )\n}\n\n// Generic components\ninterface ListProps<T> {\n  items: T[]\n  renderItem: (item: T) => React.ReactNode\n}\n\nfunction List<T>({ items, renderItem }: ListProps<T>) {\n  return <>{items.map(renderItem)}</>\n}\n\nMigration Checklist\nPre-Migration\n Upgrade dependencies incrementally\n Review breaking changes in release notes\n Set up comprehensive test coverage\n Create feature branch\nClass → Hooks\n Start with leaf components (no children)\n Convert state to useState\n Convert lifecycle to useEffect\n Extract shared logic to custom hooks\n Convert HOCs to hooks where possible\nReact 18+ Upgrade\n Update to createRoot API\n Test with StrictMode double-invocation\n Address hydration mismatches\n Adopt Suspense boundaries where beneficial\n Use transitions for expensive updates\nPost-Migration\n Run full test suite\n Check for console warnings\n Profile performance before/after\n Document changes for team\nNEVER\nSkip testing after migration\nMigrate multiple components in one commit\nIgnore StrictMode warnings (they reveal bugs)\nUse // eslint-disable-next-line react-hooks/exhaustive-deps without understanding why\nMix class and hooks in same component"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/wpank/react-modernization",
    "publisherUrl": "https://clawhub.ai/wpank/react-modernization",
    "owner": "wpank",
    "version": "1.0.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/react-modernization",
    "downloadUrl": "https://openagent3.xyz/downloads/react-modernization",
    "agentUrl": "https://openagent3.xyz/skills/react-modernization/agent",
    "manifestUrl": "https://openagent3.xyz/skills/react-modernization/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/react-modernization/agent.md"
  }
}