Components & Props
Checking access...
Components are the building blocks of any React application. Props (short for “properties”) are how you pass data from a parent component to a child component.
What Are Props?
Props are read-only arguments passed to components, similar to function parameters:
// Child component receives props as an objectfunction Greeting(props) { return <h1>Hello, {props.name}!</h1>;}
// Parent passes props like HTML attributesfunction App() { return ( <div> <Greeting name="Alice" /> <Greeting name="Bob" /> <Greeting name="Charlie" /> </div> );}Destructuring Props
// Instead of props.name, props.age:function UserCard({ name, age, role }) { return ( <div className="card"> <h2>{name}</h2> <p>Age: {age}</p> <p>Role: {role}</p> </div> );}
// Usage<UserCard name="Alice" age={30} role="Developer" />Passing Different Prop Types
function PropDemo({ string, // "hello" number, // {42} boolean, // {true} or just the prop name array, // {[1, 2, 3]} object, // {{ key: "value" }} function, // {() => doSomething()}}) { return <>{/* ... */}</>;}
// Usage<PropDemo string="hello" number={42} boolean // shorthand for boolean={true} array={[1, 2, 3]} object={{ name: "Alice" }} function={() => console.log("clicked")}/>Tip
Boolean props can use shorthand — <Button disabled /> is equivalent to <Button disabled={true} />.
Default Props (Default Parameters)
Use JavaScript default parameters for optional props:
function Button({ label = "Click Me", variant = "primary", disabled = false }) { return ( <button className={`btn btn-${variant}`} disabled={disabled}> {label} </button> );}
// All of these work:<Button /><Button label="Save" /><Button label="Delete" variant="danger" disabled />The children Prop
children is a special prop for passing content between opening and closing tags:
function Card({ title, children }) { return ( <div className="card"> <h2 className="card-title">{title}</h2> <div className="card-content">{children}</div> </div> );}
function App() { return ( <Card title="Welcome"> <p>This content is passed as children.</p> <p>You can pass anything — elements, text, or other components.</p> </Card> );}Children Patterns
// Text child<Button>Click Me</Button>
// Element child<Card><p>Content</p></Card>
// Multiple children<Panel> <Header /> <Body /> <Footer /></Panel>
// Function as child (render prop pattern)<DataProvider> {(data) => <List items={data} />}</DataProvider>
// No children — self-closing<Icon />Component Composition
Composition is combining small components to build larger ones:
function Avatar({ src, alt }) { return <img className="avatar" src={src} alt={alt} />;}
function UserInfo({ name, role }) { return ( <div className="user-info"> <h3>{name}</h3> <p>{role}</p> </div> );}
function UserCard({ user }) { return ( <div className="user-card"> <Avatar src={user.avatar} alt={user.name} /> <UserInfo name={user.name} role={user.role} /> </div> );}
function UserList({ users }) { return ( <div className="user-list"> {users.map((user) => ( <UserCard key={user.id} user={user} /> ))} </div> );}Props Patterns
Spread Props
const user = { name: "Alice", age: 30, role: "Developer" };
// Manually:<UserCard name={user.name} age={user.age} role={user.role} />
// Spread:<UserCard {...user} />Conditional Props
<Button {...(isLoading ? { disabled: true, children: "Loading..." } : { onClick: handleClick, children: "Save" })} />Component as Prop
function Menu({ icon: Icon, title }) { return ( <div className="menu-item"> <Icon /> <span>{title}</span> </div> );}
<Menu icon={HomeIcon} title="Home" /><Menu icon={SettingsIcon} title="Settings" />Props Are Read-Only
Never modify props inside a component:
// ❌ Never do thisfunction BadComponent(props) { props.name = "New Name"; // mutates the prop! return <h1>{props.name}</h1>;}
// ✅ Props are read-only — use state for mutable datafunction GoodComponent({ name }) { const [displayName, setDisplayName] = useState(name); return <h1>{displayName}</h1>;}React components must be pure functions with respect to their props — given the same props, they should always render the same output.
One-Way Data Flow
Data flows down the component tree — from parent to child through props:
App├── UserList (passes users array)│ ├── UserCard (receives single user)│ │ ├── Avatar (receives src, alt)│ │ └── UserInfo (receives name, role)│ └── UserCard└── FooterChildren communicate back to parents via callback functions passed as props:
function Child({ onAction }) { return <button onClick={() => onAction("Data from child")}>Send Up</button>;}
function Parent() { const handleChildAction = (data) => { console.log("Received:", data); };
return <Child onAction={handleChildAction} />;}Quick Reference
| Pattern | Syntax | Use Case |
|---|---|---|
| Destructuring | function Card({ title, desc }) | Most common — clean and explicit |
| Default values | function Btn({ label = "Click" }) | Optional props |
| Children | <Card><p>Content</p></Card> | Wrapping content |
| Spread | <Card {...props} /> | Forwarding multiple props |
| Render prop | {(data) => <View data={data} />} | Flexible data rendering |
| Callback | onClick={() => handle(id)} | Child-to-parent communication |
Practice Exercises
Build a ProductCard component that accepts props for
name,price,inStock, and an optionaldiscount. Render the product info and conditionally show a “Sale!” badge when there’s a discount.Create a Layout component that uses
childrenfor content and also accepts asidebarprop for a sidebar component. Compose a page using it.Build a Button component with variants (
primary,secondary,danger), sizes (small,medium,large), and aloadingstate. Use default props for optional values.