- Spec files
npm-react
Describes: pkg:npm/react@18.3.x
- Description
- React is a JavaScript library for building user interfaces with declarative, component-based architecture.
- Author
- tessl
- Last updated
elements.md docs/
1# Element Creation & Manipulation23React elements are the building blocks of React applications. These functions provide ways to create, clone, and validate React elements programmatically, serving as alternatives to JSX syntax.45## Capabilities67### createElement89Creates React elements programmatically - the function that JSX compiles to.1011```javascript { .api }12/**13* Creates a React element14* @param type - Component type, HTML tag name, or React component15* @param props - Element props and attributes (null if no props)16* @param children - Child elements (variadic arguments)17* @returns React element18*/19function createElement<P extends {}>(20type: string | ComponentType<P>,21props?: (Attributes & P) | null,22...children: ReactNode[]23): ReactElement<P>;2425// Overloads for different element types26function createElement<P extends HTMLAttributes<T>, T extends HTMLElement>(27type: keyof ReactHTML,28props?: (ClassAttributes<T> & P) | null,29...children: ReactNode[]30): DetailedReactHTMLElement<P, T>;3132function createElement<P extends SVGAttributes<T>, T extends SVGElement>(33type: keyof ReactSVG,34props?: (ClassAttributes<T> & P) | null,35...children: ReactNode[]36): ReactSVGElement;37```3839**Usage Examples:**4041```javascript42import React, { createElement } from 'react';4344// Basic HTML elements45const heading = createElement('h1', { className: 'title' }, 'Hello World');46// Equivalent JSX: <h1 className="title">Hello World</h1>4748const paragraph = createElement('p', null, 'This is a paragraph');49// Equivalent JSX: <p>This is a paragraph</p>5051// With multiple children52const div = createElement('div', { id: 'container' },53createElement('h2', null, 'Section Title'),54createElement('p', null, 'Section content'),55createElement('button', { onClick: handleClick }, 'Click me')56);57// Equivalent JSX:58// <div id="container">59// <h2>Section Title</h2>60// <p>Section content</p>61// <button onClick={handleClick}>Click me</button>62// </div>6364// With React components65function MyComponent({ name, age }) {66return createElement('div', null,67createElement('h3', null, `Name: ${name}`),68createElement('p', null, `Age: ${age}`)69);70}7172const componentElement = createElement(MyComponent, { name: 'John', age: 30 });73// Equivalent JSX: <MyComponent name="John" age={30} />7475// Dynamic element creation76function createList(items, itemType = 'li') {77return createElement('ul', null,78...items.map((item, index) =>79createElement(itemType, { key: index }, item)80)81);82}8384const todoList = createList(['Buy milk', 'Walk dog', 'Code review']);85```8687### cloneElement8889Creates a copy of a React element with new props, preserving the original element's key and ref.9091```javascript { .api }92/**93* Clones a React element with new props94* @param element - React element to clone95* @param props - New props to merge (null to keep original props)96* @param children - New children (replaces original children)97* @returns Cloned React element with merged props98*/99function cloneElement<P extends {}>(100element: ReactElement<P>,101props?: (Partial<P> & Attributes) | null,102...children: ReactNode[]103): ReactElement<P>;104```105106**Usage Examples:**107108```javascript109import React, { cloneElement, Children } from 'react';110111// Basic cloning with new props112function ButtonGroup({ children, variant = 'primary' }) {113return (114<div className="button-group">115{Children.map(children, (child) => {116if (React.isValidElement(child)) {117return cloneElement(child, {118className: `btn btn-${variant}`,119size: 'medium'120});121}122return child;123})}124</div>125);126}127128// Usage129<ButtonGroup variant="secondary">130<button onClick={handleSave}>Save</button>131<button onClick={handleCancel}>Cancel</button>132</ButtonGroup>133134// Enhanced form field wrapper135function FormField({ children, error, touched }) {136const child = Children.only(children);137138return (139<div className={`form-field ${error && touched ? 'error' : ''}`}>140{cloneElement(child, {141className: `${child.props.className || ''} form-input`,142'aria-invalid': error && touched,143'aria-describedby': error && touched ? `${child.props.id}-error` : undefined144})}145{error && touched && (146<div id={`${child.props.id}-error`} className="error-message">147{error}148</div>149)}150</div>151);152}153154// Usage155<FormField error="Email is required" touched={true}>156<input id="email" type="email" placeholder="Enter email" />157</FormField>158159// Adding event handlers to existing elements160function WithClickTracking({ children, trackingId }) {161return Children.map(children, (child) => {162if (React.isValidElement(child)) {163const originalOnClick = child.props.onClick;164165return cloneElement(child, {166onClick: (event) => {167// Track click event168analytics.track('click', { trackingId, elementType: child.type });169170// Call original handler171if (originalOnClick) {172originalOnClick(event);173}174}175});176}177return child;178});179}180181// Higher-order component using cloneElement182function withTooltip(WrappedComponent, tooltipText) {183return function TooltipWrapper(props) {184const [showTooltip, setShowTooltip] = useState(false);185186return (187<div className="tooltip-container">188{cloneElement(<WrappedComponent {...props} />, {189onMouseEnter: () => setShowTooltip(true),190onMouseLeave: () => setShowTooltip(false)191})}192{showTooltip && (193<div className="tooltip">{tooltipText}</div>194)}195</div>196);197};198}199```200201### isValidElement202203Checks if an object is a valid React element.204205```javascript { .api }206/**207* Validates if object is a React element208* @param object - Object to validate209* @returns True if object is a valid React element210*/211function isValidElement<P>(object: {} | null | undefined): object is ReactElement<P>;212```213214**Usage Examples:**215216```javascript217import React, { isValidElement } from 'react';218219// Utility function to render different content types220function renderContent(content) {221if (isValidElement(content)) {222// It's a React element, render as-is223return content;224} else if (typeof content === 'string') {225// It's a string, wrap in paragraph226return <p>{content}</p>;227} else if (typeof content === 'function') {228// It's a function, call it229return renderContent(content());230} else {231// Convert to string232return <span>{String(content)}</span>;233}234}235236// Flexible card component237function Card({ title, content, footer }) {238return (239<div className="card">240<div className="card-header">241{isValidElement(title) ? title : <h3>{title}</h3>}242</div>243<div className="card-body">244{renderContent(content)}245</div>246{footer && (247<div className="card-footer">248{isValidElement(footer) ? footer : <p>{footer}</p>}249</div>250)}251</div>252);253}254255// Usage with different content types256<Card257title={<h2 className="custom-title">Special Title</h2>}258content={<div>Custom JSX content</div>}259footer="Simple string footer"260/>261262<Card263title="String title"264content="String content"265footer={<button>Action Button</button>}266/>267268// Conditional rendering helper269function ConditionalWrapper({ condition, wrapper, children }) {270if (condition && isValidElement(wrapper)) {271return React.cloneElement(wrapper, {}, children);272}273return children;274}275276// Usage277<ConditionalWrapper278condition={isLoggedIn}279wrapper={<div className="authenticated-content" />}280>281<UserDashboard />282</ConditionalWrapper>283284// Type-safe children processing285function ProcessChildren({ children, processor }) {286return (287<div>288{React.Children.map(children, (child) => {289if (isValidElement(child)) {290return processor ? processor(child) : child;291}292// Handle non-element children (strings, numbers, etc.)293return <span key={Math.random()}>{child}</span>;294})}295</div>296);297}298299// Filter and process valid React elements300function ElementFilter({ children, filter }) {301const validElements = React.Children.toArray(children).filter(child =>302isValidElement(child) && (!filter || filter(child))303);304305return <>{validElements}</>;306}307308// Usage - only render Button components309<ElementFilter filter={(child) => child.type === Button}>310<Button>Valid</Button>311<div>This will be filtered out</div>312<Button>Also valid</Button>313Some text will also be filtered out314</ElementFilter>315```316317### createFactory318319Creates a factory function for creating elements of a specific type (deprecated but still available).320321```javascript { .api }322/**323* Creates element factory function for specific type (deprecated)324* @param type - Component type or HTML tag name325* @returns Factory function that creates elements of the specified type326*/327function createFactory<P extends {}>(type: string | ComponentType<P>):328(props?: (Attributes & P) | null, ...children: ReactNode[]) => ReactElement<P>;329```330331**Usage Examples:**332333```javascript334import React, { createFactory } from 'react';335336// Create factories for common elements337const div = createFactory('div');338const h1 = createFactory('h1');339const button = createFactory('button');340341// Create factory for custom component342function MyComponent({ title, children }) {343return <div><h2>{title}</h2>{children}</div>;344}345const myComponent = createFactory(MyComponent);346347// Usage (equivalent to createElement calls)348const element1 = div({ className: 'container' },349h1(null, 'Title'),350button({ onClick: handleClick }, 'Click me')351);352353const element2 = myComponent({ title: 'Section' }, 'Content here');354355// Pre-bound factory with common props356function createButtonFactory(defaultProps) {357const buttonFactory = createFactory('button');358return (props, ...children) => buttonFactory({359...defaultProps,360...props361}, ...children);362}363364const primaryButton = createButtonFactory({365className: 'btn btn-primary',366type: 'button'367});368369// Usage370const saveButton = primaryButton({ onClick: handleSave }, 'Save');371const cancelButton = primaryButton({ onClick: handleCancel }, 'Cancel');372```373374## Types375376```javascript { .api }377// React element interface378interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {379type: T;380props: P;381key: Key | null;382}383384// Element creation types385type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;386type Key = string | number;387type ReactNode = ReactChild | ReactFragment | ReactPortal | boolean | null | undefined;388389// Props with standard attributes390interface Attributes {391key?: Key | null;392}393394interface RefAttributes<T> extends Attributes {395ref?: Ref<T>;396}397398interface ClassAttributes<T> extends Attributes {399ref?: LegacyRef<T>;400}401402// HTML and SVG element types403interface ReactHTML {404a: DetailedHTMLFactory<AnchorHTMLAttributes<HTMLAnchorElement>, HTMLAnchorElement>;405div: DetailedHTMLFactory<HTMLAttributes<HTMLDivElement>, HTMLDivElement>;406button: DetailedHTMLFactory<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;407// ... all other HTML elements408}409410interface ReactSVG {411svg: SVGFactory;412circle: SVGFactory;413path: SVGFactory;414// ... all other SVG elements415}416```