Use when creating components, typing props with TypeScript, forwarding refs, or implementing component composition patterns. Prevents the common mistake of using incorrect prop typing or missing forwardRef when exposing DOM elements. Covers function component typing, children patterns, React.memo, forwardRef, React.lazy, createPortal, compound components, render props, HOCs. Keywords: component, props, children, forwardRef, React.memo, Portal, lazy, create component, TypeScript props, children prop, wrap component, higher-order component..
Use when creating components, typing props with TypeScript, forwarding refs, or implementing component composition patterns. Prevents the common mistake of using incorrect prop typing or missing forwardRef when exposing DOM elements. Covers function component typing, children patterns, React.memo, forwardRef, React.lazy, createPortal, compound components, render props, HOCs. Keywords: component, props, children, forwardRef, React.memo, Portal, lazy, create component, TypeScript props, children prop, wrap component, higher-order component..
license
MIT
compatibility
Designed for Claude Code. Requires React 18.x or 19.x with TypeScript.
metadata
{"author":"OpenAEC-Foundation","version":"1.0"}
react-syntax-components
Quick Reference
Function Component Typing
Pattern
Syntax
When
Props interface + return
function Comp(props: Props): React.ReactElement
Default for all components
Destructured props
function Comp({ name, age }: Props)
When accessing props directly
Generic component
function List<T>(props: ListProps<T>)
Reusable data-driven components
Default props
{ size = 'md' }: Props
Optional props with defaults
Component API Quick Lookup
API
Purpose
React 18
React 19
React.memo
Skip re-render when props unchanged
Yes
Yes (Compiler reduces need)
forwardRef
Pass ref through component
Required
DEPRECATED -- use ref as prop
React.lazy
Code-split with dynamic import
Yes
Yes
createPortal
Render outside DOM parent
Yes
Yes
useImperativeHandle
Expose custom ref handle
With forwardRef
With ref prop
Critical Warnings
NEVER use class components for new code -- ALWAYS use function components with hooks. Class components are legacy and cannot use hooks.
NEVER define components inside other components -- this destroys state on every render. ALWAYS define components at module scope.
NEVER call hooks conditionally inside components -- React relies on consistent hook call order. ALWAYS call hooks at the top level.
ALWAYS use TypeScript interfaces for props -- bare any or untyped props defeat type safety and make refactoring dangerous.
ALWAYS use React.ReactNode for children type -- it covers strings, numbers, elements, arrays, fragments, portals, null, and undefined.
Decision Tree: Component Pattern Selection
Need to render children?
+-- Fixed structure --> Standard props interface
+-- Flexible layout --> children: React.ReactNode
+-- Parent needs control over rendering --> Render props pattern
Need to share behavior across components?
+-- Shared state logic --> Custom hook (ALWAYS prefer this)
+-- Shared rendering wrapper --> Compound component pattern
+-- Cross-cutting concern (rare) --> HOC pattern
Need performance optimization?
+-- Expensive render, stable props --> React.memo
+-- Code splitting by route --> React.lazy + Suspense
Need DOM access from parent?
+-- React 18 --> forwardRef + useImperativeHandle
+-- React 19 --> ref as prop + useImperativeHandle
Need to render outside DOM hierarchy?
+-- Modals, tooltips, overlays --> createPortal
ALWAYS ensure parent stabilizes callback props with useCallback -- otherwise memo is ineffective because a new function reference is created every render.
React 19: The React Compiler auto-memoizes, making manual memo largely unnecessary. Keep memo for React 18 compatibility.
// React 19 -- ref callbacks can return a cleanup function
<div ref={(node) => {
// Setup: node is attached
node?.addEventListener('scroll', handleScroll);
// Cleanup: returned function runs when ref detachesreturn() => node?.removeEventListener('scroll', handleScroll);
}} />
Event bubbling: Events from portals bubble through the React tree (not the DOM tree). A click inside a portal still triggers onClick on React ancestors.
ALWAYS use portals for modals, tooltips, and overlays that must escape overflow: hidden or z-index stacking contexts.