Files
awesome-copilot/skills/react-audit-grep-patterns/references/react18-scans.md
Saravanan Rajaraman 7f7b1b9b46 feat: Adds React 18 and 19 migration plugin (#1339)
- Adds React 18 and 19 migration orchestration plugins
- Introduces comprehensive upgrade toolkits for migrating legacy React 16/17 and 18 codebases to React 18.3.1 and 19, respectively. Each plugin bundles specialized agents and skills for exhaustive audit, dependency management, class/component API migration, test suite transformation, and batching regression fixes.
- The React 18 toolkit targets class-component-heavy apps, ensures safe lifecycle and context transitions, resolves dependency blockers, and fully automates test migrations including Enzyme removal. The React 19 toolkit addresses breaking changes such as removal of legacy APIs, defaultProps on function components, and forwardRef, while enforcing a gated, memory-resumable migration pipeline.
- Both plugins update documentation, plugin registries, and skill references to support reliable, repeatable enterprise-scale React migrations.
2026-04-09 15:18:52 +10:00

7.4 KiB

React 18.3.1 Audit - Complete Scan Commands

Run in this order. Each section maps to a phase in the react18-auditor.


Phase 0 - Codebase Profile

# Total source files (excluding tests)
find src/ \( -name "*.js" -o -name "*.jsx" \) \
  | grep -v "\.test\.\|\.spec\.\|__tests__\|node_modules" \
  | wc -l

# Class component count
grep -rl "extends React\.Component\|extends Component\|extends PureComponent" \
  src/ --include="*.js" --include="*.jsx" \
  | grep -v "\.test\." | wc -l

# Function component rough count
grep -rl "const [A-Z][a-zA-Z]* = \|function [A-Z][a-zA-Z]*(" \
  src/ --include="*.js" --include="*.jsx" \
  | grep -v "\.test\." | wc -l

# Current React version
node -e "console.log(require('./node_modules/react/package.json').version)" 2>/dev/null

# StrictMode in use? (affects how many lifecycle warnings were already seen)
grep -rn "StrictMode\|React\.StrictMode" \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

Phase 1 - Unsafe Lifecycle Methods

# componentWillMount (without UNSAFE_ prefix)
grep -rn "componentWillMount\b" \
  src/ --include="*.js" --include="*.jsx" \
  | grep -v "UNSAFE_componentWillMount\|\.test\."

# componentWillReceiveProps (without UNSAFE_ prefix)
grep -rn "componentWillReceiveProps\b" \
  src/ --include="*.js" --include="*.jsx" \
  | grep -v "UNSAFE_componentWillReceiveProps\|\.test\."

# componentWillUpdate (without UNSAFE_ prefix)
grep -rn "componentWillUpdate\b" \
  src/ --include="*.js" --include="*.jsx" \
  | grep -v "UNSAFE_componentWillUpdate\|\.test\."

# Already partially migrated with UNSAFE_ prefix? (check if team already did partial work)
grep -rn "UNSAFE_component" \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

# Quick count summary:
echo "=== Lifecycle Issue Summary ==="
echo "componentWillMount: $(grep -rn "componentWillMount\b" src/ --include="*.js" --include="*.jsx" | grep -v "UNSAFE_\|\.test\." | wc -l)"
echo "componentWillReceiveProps: $(grep -rn "componentWillReceiveProps\b" src/ --include="*.js" --include="*.jsx" | grep -v "UNSAFE_\|\.test\." | wc -l)"
echo "componentWillUpdate: $(grep -rn "componentWillUpdate\b" src/ --include="*.js" --include="*.jsx" | grep -v "UNSAFE_\|\.test\." | wc -l)"

Phase 2 - Automatic Batching Vulnerabilities

# Async class methods (primary risk zone)
grep -rn "^\s*async [a-zA-Z]" \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

# Arrow function async methods
grep -rn "=\s*async\s*(" \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

# setState inside .then() callbacks
grep -rn "\.then\s*(" \
  src/ --include="*.js" --include="*.jsx" -A 3 \
  | grep "setState" | grep -v "\.test\."

# setState inside .catch() callbacks
grep -rn "\.catch\s*(" \
  src/ --include="*.js" --include="*.jsx" -A 3 \
  | grep "setState" | grep -v "\.test\."

# setState inside setTimeout
grep -rn "setTimeout" \
  src/ --include="*.js" --include="*.jsx" -A 5 \
  | grep "setState" | grep -v "\.test\."

# this.state reads that follow an await (most dangerous pattern)
grep -rn "this\.state\." \
  src/ --include="*.js" --include="*.jsx" -B 3 \
  | grep "await" | grep -v "\.test\."

# document/window event handlers with setState
grep -rn "addEventListener" \
  src/ --include="*.js" --include="*.jsx" -A 5 \
  | grep "setState" | grep -v "\.test\."

Phase 3 - Legacy Context API

# Provider side
grep -rn "childContextTypes\s*=" \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

grep -rn "getChildContext\s*(" \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

# Consumer side
grep -rn "contextTypes\s*=" \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

# this.context usage (may indicate legacy or modern - verify per hit)
grep -rn "this\.context\." \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

# Count of distinct legacy contexts (by counting childContextTypes blocks)
grep -rn "childContextTypes" \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l

Phase 4 - String Refs

# String ref assignments in JSX
grep -rn 'ref="[^"]*"' \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

# Alternative quote style
grep -rn "ref='[^']*'" \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

# this.refs accessor usage
grep -rn "this\.refs\." \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

Phase 5 - findDOMNode

grep -rn "findDOMNode\|ReactDOM\.findDOMNode" \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

Phase 6 - Root API (ReactDOM.render)

grep -rn "ReactDOM\.render\s*(" \
  src/ --include="*.js" --include="*.jsx"

grep -rn "ReactDOM\.hydrate\s*(" \
  src/ --include="*.js" --include="*.jsx"

grep -rn "unmountComponentAtNode" \
  src/ --include="*.js" --include="*.jsx"

Phase 7 - Event Delegation (React 16 Carry-Over)

# document-level event listeners (may miss React events after React 17 delegation change)
grep -rn "document\.addEventListener\|document\.removeEventListener" \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

# window event listeners
grep -rn "window\.addEventListener" \
  src/ --include="*.js" --include="*.jsx" | grep -v "\.test\."

Phase 8 - Enzyme Detection (Hard Blocker)

# Enzyme in package.json
cat package.json | python3 -c "
import sys, json
d = json.load(sys.stdin)
deps = {**d.get('dependencies',{}), **d.get('devDependencies',{})}
enzyme_pkgs = [k for k in deps if 'enzyme' in k.lower()]
print('Enzyme packages found:', enzyme_pkgs if enzyme_pkgs else 'NONE')
"

# Enzyme imports in test files
grep -rn "from 'enzyme'\|require.*enzyme" \
  src/ --include="*.test.*" --include="*.spec.*" 2>/dev/null | wc -l

Full Summary Script

Run this for a quick overview before detailed scanning:

#!/bin/bash
echo "=============================="
echo "React 18 Migration Audit Summary"
echo "=============================="
echo ""
echo "LIFECYCLE METHODS:"
echo "  componentWillMount:          $(grep -rn "componentWillMount\b" src/ --include="*.js" --include="*.jsx" | grep -v "UNSAFE_\|\.test\." | wc -l | tr -d ' ') hits"
echo "  componentWillReceiveProps:   $(grep -rn "componentWillReceiveProps\b" src/ --include="*.js" --include="*.jsx" | grep -v "UNSAFE_\|\.test\." | wc -l | tr -d ' ') hits"
echo "  componentWillUpdate:         $(grep -rn "componentWillUpdate\b" src/ --include="*.js" --include="*.jsx" | grep -v "UNSAFE_\|\.test\." | wc -l | tr -d ' ') hits"
echo ""
echo "LEGACY APIS:"
echo "  Legacy context (providers):  $(grep -rn "childContextTypes" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"
echo "  String refs (this.refs):     $(grep -rn "this\.refs\." src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"
echo "  findDOMNode:                 $(grep -rn "findDOMNode" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"
echo "  ReactDOM.render:             $(grep -rn "ReactDOM\.render\s*(" src/ --include="*.js" --include="*.jsx" | wc -l | tr -d ' ') hits"
echo ""
echo "ENZYME (BLOCKER):"
echo "  Enzyme test files:           $(grep -rl "from 'enzyme'" src/ --include="*.test.*" 2>/dev/null | wc -l | tr -d ' ') files"
echo ""
echo "ASYNC BATCHING RISK:"
echo "  Async class methods:         $(grep -rn "^\s*async [a-zA-Z]" src/ --include="*.js" --include="*.jsx" | grep -v "\.test\." | wc -l | tr -d ' ') hits"