Aalexbit-codemod

nested-component-fix

Detect and fix React components defined inside other components — hoists inner components to module level to preserve state and avoid unnecessary re-creation

reacttransformationperformancestate
Public
4 executions
0 stars
How to Use
Run this codemod on your codebase using one of the following commands

The easiest way to run this codemod without installing anything globally:

Documentation

nested-component-fix

Detects and fixes React components defined inside other components — hoists inner components to module level to preserve state and avoid unnecessary re-creation on every render.

Problem

Defining a component inside another component's body creates a new function reference on each render. That:

  • Destroys component state on every parent re-render
  • Hurts performance
  • Can cause infinite re-render loops

Solution

The codemod hoists inner component definitions to the module level so they stay stable across renders.

Usage

bash

Branch creation (on by default): Use --param create_branch=false to skip creating a branch. When on, a branch is created first and commits are made after each step.

Publish branch (always runs last): Pushes the local branch to remote.

Create PR (off by default): Use --param publish_pr=true to create a PR targeting the main branch. Requires gh CLI (or --param api_token=<token> for GitHub API). Optional params: main_branch (default: main), pr_title, pr_body.

Metrics

  • effort-automated: Cases fixed by the AST codemod (no closure over outer scope)
  • effort-remained: Tricky cases skipped (closure over outer scope, etc.) — use the optional AI step for these

Cardinalities (for aggregation):

  • change_type: automated-by-codemod | to-be-done-by-ai-or-human
  • change_difficulty_category: simple | complex (closure refactors are complex; malformed-declaration is simple)

Create PR (Optional, runs last)

Run with --param publish_pr=true to create a PR after pushing the branch. The workflow first pushes the branch to remote, then optionally creates a PR. Requires gh CLI or api_token for GitHub API. Off by default. Optional params: main_branch (default: main), pr_title, pr_body, api_token (for CI/automation).

Tricky Cases (Optional AI Step)

Run with --param run_ai_step=true to fix cases the codemod skips:

  • Inner component uses variables from outer scope (closure) — refactor to pass as props
  • Complex nesting (A inside B inside C)
  • Conditionally defined components

What Gets Fixed

Automated (no AI):

  • const Inner = () => <div>...</div> inside a component
  • Inner component used as <Inner /> or <Inner>...</Inner>
  • No closure over outer scope

Skipped (effort-remained, use AI step):

  • Inner component references outer scope (useState, props, local vars)
  • Conditionally defined components

Ready to contribute?

Build your own codemod and share it with the community.