Customizing Components with Props in React

Props (properties) are essential for customising React components. They allow you to send information from a parent component to a child component via JSX element parameters. Building dynamic apps requires this flexibility to adjust components to diverse contexts. JSX elements accept props. Though they resemble HTML props, they may hold JavaScript data types including numbers, strings, functions, arrays, and even React components. Custom components can display or interact with data using props. Props are essential to creating adaptable components, and learning about them can help you create custom ones for specific situations.
What are Props?
A key idea in React is props, which stand for properties and are a used to transport data between and customise components. They enable a parent component to communicate with its child components by acting as parameters given to a JSX element. This approach is essential for developing dynamic, reusable, and flexible components that may adjust to various inputs without having their display logic closely tied to particular values.
Describe props. Similar to HTML attributes, props are essentially arguments that you give to a JSX element. But unlike regular HTML properties, React props are not preset and can take a variety of JavaScript data types, such as:
Strings and Numbers: One of the main ways to transfer data and make components dynamic and reusable in React is to customise them with props. Props, which stand for “properties,” are arguments that are passed to JSX elements so that data can go from a parent component to its offspring.
Arrays: Arrays are helpful for transmitting lists of data, like the AnimalCard example’s diet. It might be necessary to use join() or similar techniques to transform arrays supplied as props to strings for display.
Objects: To pass an object as a prop in React, use curly brackets {} in JSX, similar to other JavaScript expressions. For example, an AnimalCard component may get a prop with notes or link attributes, such as {animal.additional}. To access object props in the receiving component, use object destructuring in functional components (e.g., function AnimalCard({ additional }) {… }) or dot notation in class components (e.g., this.props.additional).
Functions: Makes callback mechanisms possible, allowing a child component to interact with its parent or initiate parent operations. For example, a function that is triggered when the component is clicked can be passed to a onClick prop. Immutable props cannot be altered within a component after they are supplied. When a parent component changes a prop’s value, React replaces it. The component will then re-render with the modified values.
Passing and Accessing Props
Going Past and To Props JSX passes props to components using attributes-like syntax. For JavaScript expressions including variables, numbers, arrays, objects, or functions, the value is encased in curly braces {}. The name property of an animal object is supplied as a prop with name={animal.name}. A single props object is created when a component receives props. This.props is the class component that provides access to these props. Props can be destructured to make particular properties easier to access, and they are received as the function’s first argument in functional components.
Special Prop: kids Props.children is a unique prop that enables components to encircle unknown components or content by acting as wrapper components. The children prop is the text that is supplied between the opening and closing JSX tags of a component.
Modals, template pages, and information tiles are examples of generic user interface elements that are especially helpful for giving their child components a default structure. A single JSX element or an array can be the children prop. Useful React functions include React.Working with these kids? Use Children.map and React.cloneElement.
The Prop and Wrapper Components
React’s props.children collects stuff between a component’s opening and closing JSX tags. This built-in prop helps construct wrapper components.
Wrapper components help UI elements have a standard structure by encapsulating unknown child components or JSX. Modals, template pages, info tiles, buttons, alerts can be used. A Card component may define a standard border and title, while its children prop renders each card instance’s content.
The children prop can be a single or array of JSX items. Like React, React provides utility functions.Iterate and manage children with Children.map. React to kid manipulation.Since props are immutable, cloneElement merges new props with existing ones. The powerful children prop can only be used once. Passing components as props allows bespoke JSX at many locations within a component. This allows numerous components or JSX snippets to be given and rendered in the wrapper component, giving maximum flexibility.
Ensuring Predictability with PropTypes
Prop validation in React improves predictability, readability, and error prevention as apps scale.
PropTypes: This light type system specifies the data a component expects for each prop.
- Developers use PropTypes for error checking and documentation.
- They are runtime checks that build code but display a console warning in development mode if props do not match the expected type. These vary from static type systems like TypeScript, which warn at build time.
- PropTypes include string, number, bool, func, array, and object. For more complicated data structures, PropTypes.arrayOf() and PropTypes.shape() can provide array content and object structure.
- The.isRequired modifier requires a prop.
defaultProps: This functionality lets you set component prop defaults or fallbacks. To avoid runtime problems when optional props are missing, always add default values, especially for objects and functions. DefaultProps help components operate reliably and adapt to undefined props.
Optimizing Performance with Props (Memoization)
Dynamic components require props, yet frequent rendering can degrade performance. Although their props remain unchanged, React components automatically re-render when their parent component does. This can affect “data-heavy” components with expensive calculations. Avoid this with React hooks:
React.memo: If props haven’t changed, React.memo memoizes functional components to avoid re-renders.
- The === operator compares props shallowly in memo. The component’s render is skipped if the comparison shows no change.
- A shallow comparison means that memo will still cause a re-render if a prop is an object or function, even if its content is conceptually the same, because their memory reference may change with each parent component re-render.
UseMemo Hook: Caches expensive data calculations in a component. useMemo takes a function and dependencies. Rerunning the function returns the cached value unless any dependencies change. This limits intensive computations to when needed.
useCallback Hook: The useCallback Hook memoizes methods to prevent them from being recreated on every parent component render. UseCallback takes a function and dependency array like useMemo. The memoized callback only updates if one of the dependencies changes. Passing functions as props to memo-ized child components preserves their referential identity and saves wasteful child re-renders.
Although powerful for performance optimisation, these memoization approaches have a tiny performance cost for comparison. When re-rendering causes a clear performance issue, they should be used sparingly.
Code Example:
// App.js
import React, { useState, useCallback, useMemo } from 'react';
const Child = React.memo(({ number, onClick }) => {
console.log('Child re-rendered');
return (
<div style={{ border: '1px solid black', padding: '10px' }}>
<p>Squared Value: {number}</p>
<button onClick={onClick}>Click Me</button>
</div>
);
});
function App() {
const [count, setCount] = useState(0);
const [num, setNum] = useState(2);
// Memoize expensive calculation
const squared = useMemo(() => {
console.log('Calculating square...');
return num * num;
}, [num]);
// Memoize callback to prevent re-creation on every render
const handleClick = useCallback(() => {
alert('Button in Child clicked!');
}, []);
return (
<div style={{ padding: '20px' }}>
<h2>React Memoization Example</h2>
<button onClick={() => setCount(count + 1)}>Increase Count ({count})</button>
<button onClick={() => setNum(num + 1)}>Change Num ({num})</button>
<Child number={squared} onClick={handleClick} />
</div>
);
}
export default App;
Output:
React Memoization Example
Increase Count (3)Change Num (5)
Squared Value: 25
Click Me
Props in the Broader React Ecosystem
Many sophisticated React capabilities and patterns depend on props:
Component Composition: React promotes sophisticated UIs with fewer, focused components. Props allow data to move between constructed parts.
Context API: The Context API lets deep-nested components share state without “prop drilling” (passing props via many components). The Provider can give data to the Consumer using context and the useContext Hook.
Redux: A popular third-party state management framework, Redux, connects components to a central data store. Components call “actions” to change the store and get updated state via connect or useSelector hooks.
React Router: React Router gives route-related information to components in single-page apps using props. UseParams and useLocation hooks let components access dynamic routing data via props.
Forms: React forms are “controlled” or “uncontrolled”. Form input values in controlled components are updated via props by React state, keeping the UI current.
Higher Order Components (HOCs): Props are injected into Higher Order Components (HOCs) to increase their capabilities. Using PureComponent instead of Component automatically implements shouldComponentUpdate() with shallow prop and state comparison. This reduces unnecessary renderings, improving application performance. This implies your components are ‘Pure’ and always produce the same state and props.
React programming relies on props to build modular, maintainable, and customisable apps. Developers can design complex and responsive online experiences by learning how to pass, access, and validate props and optimise their performance.