React18 Legacy Context
GitHubOfficialFirst committed by SaravananRajaramanDistributed by GitHub
- Skill
- Workflow
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a systematic approach to migrating legacy React context (contextTypes, childContextTypes, getChildContext) to the modern createContext API. Because legacy context is removed in React 19, this migration is critical for upgrading codebases. The skill emphasizes that this is a cross-file operation requiring simultaneous updates to both the provider and all consumers to prevent runtime failures. It includes scanning commands, file templates, and strategies for handling multiple contexts.
What it does
- Provides a step-by-step migration procedure for legacy React context.
- Offers shell commands to identify legacy providers and consumers in a codebase.
- Includes templates for creating new, modular context files.
- Explains how to split combined legacy providers into individual modern context providers.
- Details strategies for updating class-based consumers to modern standards.
- Outlines the correct order of operations to avoid broken application states.
When to use it
- When upgrading a React application to version 18 or preparing for version 19.
- When refactoring class components that rely on legacy contextTypes.
- When you need to replace deprecated getChildContext patterns.
- When managing complex applications with multiple nested legacy contexts.
Advantages
- Prevents common runtime errors caused by partial migrations.
- Standardizes the structure of new context files across the project.
- Provides clear, actionable steps to minimize downtime during refactoring.
- Offers specific patterns for handling multiple contexts in a single component.
Usage examples
- “How do I find all components using legacy context in my project?”
- The agent provides grep commands to scan for childContextTypes, getChildContext, and contextTypes to map out the migration scope.
- “I have a class component using multiple legacy contexts. How do I migrate it?”
- The agent guides you to either use Context.Consumer render props or convert the component to a function component using multiple useContext hooks.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/github/react18-legacy-context/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip react18-legacy-context.zip -d .agents/skills
Documentation by SaravananRajaraman
React 18 Legacy Context Migration
Legacy context (contextTypes, childContextTypes, getChildContext) was deprecated in React 16.3 and warns in React 18.3.1. It is removed in React 19.
This Is Always a Cross-File Migration
Unlike most other migrations that touch one file at a time, context migration requires coordinating:
Create the context object (usually a new file)
Update the provider component
Update every consumer component
Missing any consumer leaves the app broken - it will read from the wrong context or get undefined.
Migration Steps (Always Follow This Order)
Step 1: Find the provider (childContextTypes + getChildContext)
Step 2: Find ALL consumers (contextTypes)
Step 3: Create the context file
Step 4: Update the provider
Step 5: Update each consumer (class components → contextType, function components → useContext)
Step 6: Verify - run the app, check no legacy context warnings remainScan Commands
# Find all providers
grep -rn "childContextTypes\|getChildContext" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
# Find all consumers
grep -rn "contextTypes\s*=" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."
# Find this.context usage (may be legacy or modern - check which)
grep -rn "this\.context\." src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."Reference Files
references/single-context.md- complete migration for one context (theme, auth, etc.) with provider + class consumer + function consumerreferences/multi-context.md- apps with multiple legacy contexts (nested providers, multiple consumers of different contexts)references/context-file-template.md- the standard file structure for a new context module
Files
- ATTRIBUTION.mdAdded by AutoGineer897 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md2.4 KiB
- references/context-file-template.md3.2 KiB
- references/multi-context.md5.6 KiB
- references/single-context.md5.1 KiB
references/single-context.md
Single Context Migration - Complete Before/After
Full Example: ThemeContext
This covers the most common pattern - one context with one provider and multiple consumers.
Step 1 - Before State (Legacy)
ThemeProvider.js (provider):
import PropTypes from 'prop-types';
class ThemeProvider extends React.Component {
static childContextTypes = {
theme: PropTypes.string,
toggleTheme: PropTypes.func,
};
state = { theme: 'light' };
toggleTheme = () => {
this.setState(s => ({ theme: s.theme === 'light' ? 'dark' : 'light' }));
};
getChildContext() {
return {
theme: this.state.theme,
toggleTheme: this.toggleTheme,
};
}
render() {
return this.props.children;
}
}ThemedButton.js (class consumer):
import PropTypes from 'prop-types';
class ThemedButton extends React.Component {
static contextTypes = {
theme: PropTypes.string,
toggleTheme: PropTypes.func,
};
render() {
const { theme, toggleTheme } = this.context;
return (
<button className={`btn btn-${theme}`} onClick={toggleTheme}>
Toggle Theme
</button>
);
}
}ThemedHeader.js (function consumer - if any):
// Function components couldn't use legacy context cleanly
// They had to use a class wrapper or render propStep 2 - Create Context File
src/contexts/ThemeContext.js (new file):
import React from 'react';
// Default value matches the shape of getChildContext() return
export const ThemeContext = React.createContext({
theme: 'light',
toggleTheme: () => {},
});
// Named export for the context - both provider and consumers import from hereStep 3 - Update Provider
ThemeProvider.js (after):
import React from 'react';
import { ThemeContext } from '../contexts/ThemeContext';
class ThemeProvider extends React.Component {
state = { theme: 'light' };
toggleTheme = () => {
this.setState(s => ({ theme: s.theme === 'light' ? 'dark' : 'light' }));
};
render() {
// React 19 JSX shorthand: <ThemeContext value={...}>
// React 18: <ThemeContext.Provider value={...}>
return (
<ThemeContext.Provider
value={{
theme: this.state.theme,
toggleTheme: this.toggleTheme,
}}
>
{this.props.children}
</ThemeContext.Provider>
);
}
}
export default ThemeProvider;React 19 note: In React 19 you can write
<ThemeContext value={...}>directly (no.Provider). For React 18.3.1 use<ThemeContext.Provider value={...}>.
Step 4 - Update Class Consumer
ThemedButton.js (after):
import React from 'react';
import { ThemeContext } from '../contexts/ThemeContext';
class ThemedButton extends React.Component {
// singular contextType (not contextTypes)
static contextType = ThemeContext;
render() {
const { theme, toggleTheme } = this.context;
return (
<button className={`btn btn-${theme}`} onClick={toggleTheme}>
Toggle Theme
</button>
);
}
}
export default ThemedButton;Key differences from legacy:
static contextType(singular) notcontextTypes(plural)No PropTypes declaration needed
this.contextis the full value object (not a partial - whatever you passed tovalue)Only ONE context per class component via
contextType- useContext.Consumerrender prop for multiple
Step 5 - Update Function Consumer
ThemedHeader.js (after - now straightforward with hooks):
import { useContext } from 'react';
import { ThemeContext } from '../contexts/ThemeContext';
function ThemedHeader({ title }) {
const { theme } = useContext(ThemeContext);
return <h1 className={`header-${theme}`}>{title}</h1>;
}Step 6 - Multiple Contexts in One Class Component
If a class component consumed more than one legacy context, it gets complex. Class components can only have one static contextType. For multiple contexts, use the render prop form:
import { ThemeContext } from '../contexts/ThemeContext';
import { AuthContext } from '../contexts/AuthContext';
class Dashboard extends React.Component {
render() {
return (
<ThemeContext.Consumer>
{({ theme }) => (
<AuthContext.Consumer>
{({ user }) => (
<div className={`dashboard-${theme}`}>
Welcome, {user.name}
</div>
)}
</AuthContext.Consumer>
)}
</ThemeContext.Consumer>
);
}
}Or consider migrating the class component to a function component to use useContext cleanly.
Verification Checklist
After migrating one context:
# Provider - no legacy context exports remain
grep -n "childContextTypes\|getChildContext" src/ThemeProvider.js
# Consumers - no legacy context consumption remains
grep -rn "contextTypes\s*=" src/ --include="*.js" --include="*.jsx" | grep -v "ThemeContext\|\.test\."
# this.context usage - confirm it reads from contextType not legacy
grep -rn "this\.context\." src/ --include="*.js" | grep -v "\.test\."Each should return zero hits for the migrated context.
Requirements and compatibility
Written for: GitHub Copilot
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- First committed by
SaravananRajaraman
- Publisher
- GitHub (Official)
- Distributed by
- GitHub
- Source
- github/awesome-copilot · skills/react18-legacy-context · commit 797337f
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Contributors
- SaravananRajaraman
AutoGineer is not affiliated with or endorsed by SaravananRajaraman or GitHub.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download react18-legacy-context.zip