Files
Daniil 6e82165566
compute / deploy (push) Has been cancelled
chore: agentic upgrade
2026-05-17 02:12:18 +03:00

4.3 KiB

React Composition Rules

This reference distills the upstream Vercel composition-patterns skill. The upstream directory was inspected as a whole: SKILL.md, README.md, metadata.json, generated AGENTS.md, _sections.md, _template.md, and all rule files under rules/.

Rule Inventory

Area Rule Use it to
Architecture Avoid boolean prop proliferation Replace mode booleans with explicit composed variants.
Architecture Use compound components Let consumers arrange subcomponents that share context.
State Decouple state management from UI Keep concrete hooks/stores inside providers.
State Define generic context interfaces Share UI across providers using state, actions, meta.
State Lift state into providers Let outer/sibling components access composer-like state without refs or effects.
Patterns Create explicit component variants Make each mode self-documenting and impossible-state-free.
Patterns Prefer children over render props Use children for structure; reserve render props for data callbacks.
React 19 Ref and context API changes Use ref as a prop and use(Context) when the codebase is React 19+.

Core Principles

  • Composition over configuration: let consumers assemble behavior from parts instead of adding props for every mode.
  • State belongs at the provider boundary when more than one child or sibling needs it.
  • Compound internals should read shared context, not receive long prop chains.
  • Explicit variants are clearer than a single component with many conditional branches.

Refactoring Checklist

  1. Count behavior flags and conditional branches. Two or more mode booleans are a strong signal to split variants.
  2. Identify shared primitives. Extract the stable pieces first: frame, input, header, footer, trigger, content, action, item, or slot-like sections.
  3. Decide the provider boundary. Put it around every component that needs the shared state, even if some of those components are visually outside the main frame.
  4. Define the context shape before wiring UI. Prefer:
interface ComponentContextValue {
	state: ComponentState
	actions: ComponentActions
	meta: ComponentMeta
}
  1. Move implementation-specific hooks into provider variants. For example, LocalComposerProvider, ChannelComposerProvider, and EditComposerProvider can implement the same UI contract.
  2. Replace renderX props with children when the consumer is only placing static structure.
  3. Keep render props when the parent must provide data to each render, such as list items, indices, or measured layout values.
  4. For React 19 code, avoid adding new forwardRef wrappers unless compatibility with React 18 or an existing library API requires it.

Review Smells

  • A component accepts several props named is*, show*, has*, or mode and uses them to render different major sections.
  • A caller can pass contradictory props, such as isEditing and isForwarding.
  • A reusable UI component imports a feature store, route-specific hook, or sync mechanism directly.
  • State is copied upward through useEffect solely so another sibling can read it.
  • A submit button reads state from a ref because the state is trapped inside a child component.
  • renderHeader, renderFooter, or renderActions props are used only to place static nodes.

Repo Adaptation

  • Put generic primitives in src/shared/ui/<Component>/ with the repo's usual source, SCSS module, test, story, and barrel layout.
  • Keep feature-specific provider variants out of shared if they import feature/entity/page state.
  • Export public compound pieces through index.ts instead of deep imports.
  • Coordinate with react-best-practices for performance, Server Component boundaries, serialization, and client bundle impact.
  • Coordinate with storybook-ai-best-practices when adding stories so each compound part, variant, and state has focused examples.

Source Notes

The upstream skill is version 1.0.0, dated January 2026, and references React documentation for context and the use API. Its generated AGENTS.md is a compiled form of the individual rules, so prefer this distilled reference for day-to-day work and consult the upstream repo only when refreshing the skill.