~2 min read • Updated Oct 22, 2025
Introduction
React applications are built as trees of components. While we often use components as self-closing tags, React also supports opening and closing tags — enabling component composition. This allows us to pass content between tags and access it via the children prop.
Using Children for Composition
Instead of passing a label prop, we can place content between the component’s tags:
<InputWithLabel ...>
Search:
</InputWithLabel>Inside the component, we access this content using children:
const InputWithLabel = ({ id, value, onInputChange, children }) => (
<>
<label htmlFor={id}>{children}</label>
<input id={id} value={value} onChange={onInputChange} />
>
);This makes the component flexible and composable, allowing us to inject strings, HTML elements, or even other React components.
Declarative Focus with autoFocus
To focus an input field declaratively, we can use the autoFocus attribute:
<input autoFocus />To make this behavior configurable, we pass a prop like isFocused:
<InputWithLabel isFocused />And use it inside the component:
<input autoFocus={isFocused} />Imperative Focus with useRef
For more control, we can set focus programmatically using useRef and useEffect:
const inputRef = React.useRef();
React.useEffect(() => {
if (isFocused && inputRef.current) {
inputRef.current.focus();
}
}, [isFocused]);Then assign the ref to the input element:
<input ref={inputRef} ... />Step-by-Step Breakdown
- (A) Create a ref with
useRef. - (B) Attach it to the input’s
refattribute. - (C) Use
useEffectto trigger focus whenisFocusedchanges. - (D) Access the DOM element via
ref.currentand callfocus().
Conclusion
React’s component composition and children prop allow for flexible, expressive UI design. Combined with imperative access via useRef, we can build components that are both declarative and interactive. These patterns are essential for building reusable, scalable, and dynamic React applications.
Written & researched by Dr. Shahin Siami