К основному содержанию
скилл Claude Code CX Codex Cursor

react-modernization — скилл для Claude Code: что делает

Скилл обновляет React-код, переносит классовые компоненты на хуки и помогает внедрять возможности React 18. Подойдёт для поэтапной модернизации старого приложения.

Установить в Claude Code · Через маркетплейс плагинов Все способы и платформы ↓
/plugin marketplace add wshobson/agents
/plugin install framework-migration@claude-code-workflows
Открыть на GitHub

Что делает react-modernization

react-modernization помогает обновлять React-приложения по пути React 16 → 17 → 18, разбирать изменения между версиями и переходить от классовых компонентов к функциональным. Он охватывает перенос состояния, lifecycle-методов, Context и HOC на хуки, а также обновление до TypeScript.

Скилл объясняет настройку нового root API, автоматическую группировку обновлений, transitions и Suspense. Для автоматического рефакторинга предусмотрены codemods, а дополнительные шаблоны и примеры находятся в references/details.md. При переходе нужно учитывать изменения Strict Mode, event delegation и поведения эффектов.

Ставьте его, если в проекте есть классовый React-код или планируется переход на React 18. Для небольшого приложения без такой миграции он, скорее всего, не нужен.

Какие задачи решает

  • обновить приложение с React 16 до React 18
  • перенести классовые компоненты на хуки
  • заменить lifecycle-методы на useEffect
  • переписать Context и HOC через хуки
  • внедрить transitions и Suspense

Примеры запросов агенту

  • Перенеси `DataFetcher` с lifecycle-методов на `useEffect` и сохрани отмену запроса.
  • Обнови точку входа с `ReactDOM.render` на `createRoot` из `react-dom/client`.
  • Проверь, какие codemods нужны для миграции классовых компонентов на хуки.

Как установить react-modernization

1Через маркетплейс плагинов

/plugin marketplace add wshobson/agents
/plugin install framework-migration@claude-code-workflows

2Через Skills CLI (Vercel)

npx skills add wshobson/agents --skill react-modernization -a claude-code

3Вручную: положить файлы

~/.claude/skills/react-modernization/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/react-modernization/

Похожие

prototype Matt Pocock Создаёт временный прототип, чтобы проверить логику, модель состояния или вид интерфейса до работы над основным кодом. Claude Code 986 201установок webapp-testing официальный anthropics Скилл запускает проверки локальных веб-приложений через Playwright: помогает отлаживать UI, делать скриншоты и смотреть логи браузера. Claude Code Claude.ai 186 758установок web-artifacts-builder официальный anthropics Скилл собирает сложные HTML-артефакты для claude.ai на React, Tailwind CSS и shadcn/ui. Подходит для интерфейсов с состоянием и маршрутизацией. Claude Code Claude.ai 112 122установок theme-factory официальный anthropics Применяет готовые цветовые палитры и пары шрифтов к слайдам, документам и HTML-страницам. Подходит, когда материалу нужен единый стиль. Claude Code Claude.ai 94 921установок algorithmic-art официальный anthropics Создаёт генеративное искусство на p5.js с seed-случайностью и настройкой параметров. Подходит для flow fields, частиц и кодовых арт-экспериментов. Claude Code Claude.ai 89 081установок chrome-devtools официальный github Управляет живым Chrome через Chrome DevTools MCP: открывает страницы, проверяет ошибки и пишет трассы производительности. Нужен для отладки интерфейса прямо из агента. GitHub Copilot 15 258установок

Вопросы о react-modernization

Как установить react-modernization в Claude Code?

Выполните npx skills add wshobson/agents --skill react-modernization -a claude-code. Файл скилла появится по пути ~/.claude/skills/react-modernization/SKILL.md.

Что делает react-modernization?

Скилл помогает обновлять React-приложения, переносить классовые компоненты на хуки и применять возможности React 18, включая transitions и Suspense.

Что нужно учесть при переходе с React 17 на React 18?

Нужно заменить ReactDOM.render на createRoot, проверить автоматическую группировку обновлений и изменения Strict Mode. Также меняется поведение некоторых эффектов и появляется concurrent rendering.

Исходный текст

SKILL.md · MIT
---
name: react-modernization
description: Upgrade React applications to latest versions, migrate from class components to hooks, and adopt concurrent features. Use when modernizing React codebases, migrating to React Hooks, or upgrading to latest React versions.
---

# React Modernization

Master React version upgrades, class to hooks migration, concurrent features adoption, and codemods for automated transformation.

## When to Use This Skill

- Upgrading React applications to latest versions
- Migrating class components to functional components with hooks
- Adopting concurrent React features (Suspense, transitions)
- Applying codemods for automated refactoring
- Modernizing state management patterns
- Updating to TypeScript
- Improving performance with React 18+ features

## Version Upgrade Path

### React 16 → 17 → 18

**Breaking Changes by Version:**

**React 17:**

- Event delegation changes
- No event pooling
- Effect cleanup timing
- JSX transform (no React import needed)

**React 18:**

- Automatic batching
- Concurrent rendering
- Strict Mode changes (double invocation)
- New root API
- Suspense on server

## Class to Hooks Migration

### State Management

```javascript
// Before: Class component
class Counter extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      name: "",
    };
  }

  increment = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <div>
        <p>Count: {this.state.count}</p>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

// After: Functional component with hooks
function Counter() {
  const [count, setCount] = useState(0);
  const [name, setName] = useState("");

  const increment = () => {
    setCount(count + 1);
  };

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}
```

### Lifecycle Methods to Hooks

```javascript
// Before: Lifecycle methods
class DataFetcher extends React.Component {
  state = { data: null, loading: true };

  componentDidMount() {
    this.fetchData();
  }

  componentDidUpdate(prevProps) {
    if (prevProps.id !== this.props.id) {
      this.fetchData();
    }
  }

  componentWillUnmount() {
    this.cancelRequest();
  }

  fetchData = async () => {
    const data = await fetch(`/api/${this.props.id}`);
    this.setState({ data, loading: false });
  };

  cancelRequest = () => {
    // Cleanup
  };

  render() {
    if (this.state.loading) return <div>Loading...</div>;
    return <div>{this.state.data}</div>;
  }
}

// After: useEffect hook
function DataFetcher({ id }) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    let cancelled = false;

    const fetchData = async () => {
      try {
        const response = await fetch(`/api/${id}`);
        const result = await response.json();

        if (!cancelled) {
          setData(result);
          setLoading(false);
        }
      } catch (error) {
        if (!cancelled) {
          console.error(error);
        }
      }
    };

    fetchData();

    // Cleanup function
    return () => {
      cancelled = true;
    };
  }, [id]); // Re-run when id changes

  if (loading) return <div>Loading...</div>;
  return <div>{data}</div>;
}
```

### Context and HOCs to Hooks

```javascript
// Before: Context consumer and HOC
const ThemeContext = React.createContext();

class ThemedButton extends React.Component {
  static contextType = ThemeContext;

  render() {
    return (
      <button style={{ background: this.context.theme }}>
        {this.props.children}
      </button>
    );
  }
}

// After: useContext hook
function ThemedButton({ children }) {
  const { theme } = useContext(ThemeContext);

  return <button style={{ background: theme }}>{children}</button>;
}

// Before: HOC for data fetching
function withUser(Component) {
  return class extends React.Component {
    state = { user: null };

    componentDidMount() {
      fetchUser().then((user) => this.setState({ user }));
    }

    render() {
      return <Component {...this.props} user={this.state.user} />;
    }
  };
}

// After: Custom hook
function useUser() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetchUser().then(setUser);
  }, []);

  return user;
}

function UserProfile() {
  const user = useUser();
  if (!user) return <div>Loading...</div>;
  return <div>{user.name}</div>;
}
```

## React 18 Concurrent Features

### New Root API

```javascript
// 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 />);
```

### Automatic Batching

```javascript
// React 18: All updates are batched
function handleClick() {
  setCount((c) => c + 1);
  setFlag((f) => !f);
  // Only one re-render (batched)
}

// Even in async:
setTimeout(() => {
  setCount((c) => c + 1);
  setFlag((f) => !f);
  // Still batched in React 18!
}, 1000);

// Opt out if needed
import { flushSync } from "react-dom";

flushSync(() => {
  setCount((c) => c + 1);
});
// Re-render happens here
setFlag((f) => !f);
// Another re-render
```

### Transitions

```javascript
import { useState, useTransition } from "react";

function SearchResults() {
  const [query, setQuery] = useState("");
  const [results, setResults] = useState([]);
  const [isPending, startTransition] = useTransition();

  const handleChange = (e) => {
    // Urgent: Update input immediately
    setQuery(e.target.value);

    // Non-urgent: Update results (can be interrupted)
    startTransition(() => {
      setResults(searchResults(e.target.value));
    });
  };

  return (
    <>
      <input value={query} onChange={handleChange} />
      {isPending && <Spinner />}
      <Results data={results} />
    </>
  );
}
```

### Suspense for Data Fetching

```javascript
import { Suspense } from "react";

// Resource-based data fetching (with React 18)
const resource = fetchProfileData();

function ProfilePage() {
  return (
    <Suspense fallback={<Loading />}>
      <ProfileDetails />
      <Suspense fallback={<Loading />}>
        <ProfileTimeline />
      </Suspense>
    </Suspense>
  );
}

function ProfileDetails() {
  // This will suspend if data not ready
  const user = resource.user.read();
  return <h1>{user.name}</h1>;
}

function ProfileTimeline() {
  const posts = resource.posts.read();
  return <Timeline posts={posts} />;
}
```

## Additional patterns and templates

More detailed templates and worked examples live in `references/details.md`. Read that file for the full pattern library.

© Seth Hobson · MIT · wshobson/agents

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой