In React, every component must return a single root element in JSX. For example, in the Search component, we had to wrap the <label> and <input> elements inside a <div> to satisfy this rule.
To avoid adding unnecessary DOM elements, we can use React.Fragment or its shorthand <>...</>:
const Search = ({ search, onSearch }) => (
<>
>
);Fragments allow us to group elements without introducing extra nodes in the DOM.
The Search component is tightly coupled to a specific domain. To make it reusable, we rename it to InputWithLabel and generalize its props:
const InputWithLabel = ({ id, label, value, onInputChange }) => (
<>
>
);To support different input types like number or tel, we expose the type prop with a default value:
const InputWithLabel = ({
id,
label,
value,
type = 'text',
onInputChange,
}) => (
<>
>
);If no type is provided, it defaults to 'text'.
React Fragments help us return multiple elements without cluttering the DOM. By refactoring a specialized component into a generic one like InputWithLabel, we improve reusability, readability, and maintainability. These patterns are essential for building scalable and clean React applications.