Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
LoginSign Up
menu
  1. Home
  2. /Web Development
  3. /React
  4. /Props
Your Progress0%
0 of 42 completed

React Topics

Getting Started

  • What is React?
  • React vs Vanilla JavaScript
  • Setting Up Your Environment
  • Your First React App

JSX Fundamentals

  • Introduction to JSX
  • JSX Expressions and Variables
  • Conditional Rendering
  • Lists and Keys
  • Styling in JSX

Components Basics

  • Function Components
  • Props
  • Children Prop
  • Props Destructuring
  • Component Composition

State Management

  • Introduction to State
  • useState Hook
  • State Updates and Re-renders
  • Multiple State Variables
  • State Best Practices

Events and Interactivity

  • Handling Events
  • Event Objects
  • Forms in React
  • Form Validation

Side Effects and Data

  • Introduction to useEffect
  • Data Fetching
  • Cleanup Functions
  • Dependency Arrays

Advanced Hooks

  • useRef Hook
  • useContext Hook
  • useMemo Hook
  • useCallback Hook

React Patterns

  • Custom Hooks
  • Higher-Order Components
  • Render Props Pattern

React Router

  • Introduction to React Router
  • Routes and Navigation
  • Dynamic Routes and Parameters

Best Practices

  • Component Organization
  • Performance Optimization
  • Error Handling
  • Testing React Components

Real World Project

  • Building a Complete App

Props

Passing data between components

Props (short for "properties") are how you pass data from one component to another in React. They're like arguments to a function - they let you customize and reuse components with different data. In this lesson, you'll learn everything about props: how to pass them, receive them, use different types, set defaults, and understand the one-way data flow that makes React predictable and maintainable.

What Are Props?

Think of props like settings or parameters for your components. Just like you can customize a car with different colors, features, and options, you can customize React components with props.

Without props, every component would be identical:

without-props.jsx
function Greeting() {
  return <h1>Hello, World!</h1>
}

// Always says "Hello, World!" - not very useful!
<Greeting />
<Greeting />
<Greeting />

With props, the same component becomes flexible:

with-props.jsx
function Greeting(props) {
  return <h1>Hello, {props.name}!</h1>
}

// Now each greeting can be different!
<Greeting name="Alice" />   {/* Hello, Alice! */}
<Greeting name="Bob" />     {/* Hello, Bob! */}
<Greeting name="Charlie" /> {/* Hello, Charlie! */}

Props are:

  • Read-only - Components can't modify their own props
  • Passed from parent to child - Data flows downward
  • Objects - All props are bundled into one object
  • Customizable - You can pass any data type

Passing Props

You pass props to a component the same way you add attributes to HTML elements:

Basic Prop Passing

passing-props.jsx
function UserCard(props) {
  return (
    <div className="user-card">
      <h2>{props.name}</h2>
      <p>Age: {props.age}</p>
      <p>Email: {props.email}</p>
    </div>
  )
}

// Pass props like HTML attributes
function App() {
  return (
    <div>
      <UserCard 
        name="Alice Johnson" 
        age={25} 
        email="alice@example.com" 
      />
      <UserCard 
        name="Bob Smith" 
        age={30} 
        email="bob@example.com" 
      />
    </div>
  )
}

💡 String vs Expression Props

String props can use quotes: name="Alice"
Other types need curly braces: age={25}

age="25" → String "25"
age={25} → Number 25

Passing Different Data Types

prop-types.jsx
function Demo(props) {
  return (
    <div>
      <p>String: {props.text}</p>
      <p>Number: {props.count}</p>
      <p>Boolean: {String(props.isActive)}</p>
      <p>Array: {props.items.join(', ')}</p>
      <p>Object: {props.user.name}</p>
    </div>
  )
}

function App() {
  const userData = { name: 'Alice', age: 25 }
  const listItems = ['React', 'JavaScript', 'CSS']
  
  return (
    <Demo
      text="Hello"              // String
      count={42}                // Number
      isActive={true}           // Boolean
      items={listItems}         // Array
      user={userData}           // Object
      onClick={() => alert('Hi')}  // Function
    />
  )
}

Passing Expressions

prop-expressions.jsx
function ProductCard(props) {
  return (
    <div>
      <h3>{props.name}</h3>
      <p>${props.price}</p>
    </div>
  )
}

function App() {
  const basePrice = 100
  const discount = 0.2
  
  return (
    <ProductCard
      name="Laptop"
      price={basePrice * (1 - discount)}  // Expressions work!
      // This passes 80
    />
  )
}

Receiving Props

Props are passed to your component as the first parameter. It's an object containing all the props:

Accessing Props

accessing-props.jsx
function Greeting(props) {
  console.log(props)  // { name: "Alice", age: 25 }
  
  return (
    <div>
      <h1>Hello, {props.name}!</h1>
      <p>You are {props.age} years old</p>
    </div>
  )
}

// Usage:
<Greeting name="Alice" age={25} />

Using Multiple Props

multiple-props.jsx
function BlogPost(props) {
  return (
    <article>
      <h1>{props.title}</h1>
      <p className="meta">
        By {props.author} on {props.date}
      </p>
      <div className="content">
        {props.content}
      </div>
      <div className="tags">
        {props.tags.map((tag, index) => (
          <span key={index} className="tag">{tag}</span>
        ))}
      </div>
    </article>
  )
}

// Usage:
<BlogPost
  title="Understanding React Props"
  author="Jane Doe"
  date="2024-01-15"
  content="Props are awesome..."
  tags={['React', 'JavaScript', 'Tutorial']}
/>

Different Prop Types in Action

String Props

string-props.jsx
function Title(props) {
  return <h1>{props.text}</h1>
}

// Both work for strings
<Title text="Hello World" />
<Title text={'Hello World'} />

Number Props

number-props.jsx
function Counter(props) {
  return <div>Count: {props.count}</div>
}

<Counter count={42} />
<Counter count={0} />
<Counter count={-5} />
<Counter count={3.14} />

Boolean Props

boolean-props.jsx
function StatusBadge(props) {
  return (
    <span className={props.isActive ? 'active' : 'inactive'}>
      {props.isActive ? 'Online' : 'Offline'}
    </span>
  )
}

// These are equivalent:
<StatusBadge isActive={true} />
<StatusBadge isActive />  // Shorthand for true

// For false, you must be explicit:
<StatusBadge isActive={false} />

Array Props

array-props.jsx
function TagList(props) {
  return (
    <div>
      {props.tags.map((tag, index) => (
        <span key={index} className="tag">{tag}</span>
      ))}
    </div>
  )
}

<TagList tags={['React', 'JavaScript', 'Web']} />

Object Props

object-props.jsx
function UserProfile(props) {
  return (
    <div>
      <h2>{props.user.name}</h2>
      <p>Age: {props.user.age}</p>
      <p>Email: {props.user.email}</p>
    </div>
  )
}

const userData = {
  name: 'Alice',
  age: 25,
  email: 'alice@example.com'
}

<UserProfile user={userData} />

Function Props

function-props.jsx
function Button(props) {
  return (
    <button onClick={props.onClick}>
      {props.label}
    </button>
  )
}

function App() {
  const handleClick = () => {
    alert('Button clicked!')
  }
  
  return (
    <div>
      <Button label="Click Me" onClick={handleClick} />
      <Button label="Alert" onClick={() => alert('Hello!')} />
    </div>
  )
}

JSX Props

jsx-props.jsx
function Card(props) {
  return (
    <div className="card">
      <div className="card-header">
        {props.header}
      </div>
      <div className="card-body">
        {props.body}
      </div>
    </div>
  )
}

<Card
  header={<h1>Welcome</h1>}
  body={<p>This is the content</p>}
/>

Default Props

Sometimes you want props to have default values if they're not provided:

Method 1: Default Parameters

default-parameters.jsx
function Button({ label = 'Click Me', variant = 'primary' }) {
  return (
    <button className={`btn btn-${variant}`}>
      {label}
    </button>
  )
}

// Uses defaults
<Button />  
// Renders: <button class="btn btn-primary">Click Me</button>

// Overrides defaults
<Button label="Submit" variant="success" />
// Renders: <button class="btn btn-success">Submit</button>

Method 2: Logical OR (||)

logical-or.jsx
function Greeting(props) {
  const name = props.name || 'Guest'
  const greeting = props.greeting || 'Hello'
  
  return <h1>{greeting}, {name}!</h1>
}

<Greeting />  
// Renders: Hello, Guest!

<Greeting name="Alice" greeting="Welcome" />
// Renders: Welcome, Alice!

Method 3: Nullish Coalescing (??)

nullish-coalescing.jsx
function Counter(props) {
  // ?? only defaults for null/undefined, not 0 or false
  const count = props.count ?? 10
  
  return <div>Count: {count}</div>
}

<Counter />           // Count: 10
<Counter count={0} />  // Count: 0 (not 10!)
<Counter count={5} />  // Count: 5

// Compare with ||:
const count = props.count || 10
<Counter count={0} />  // Would show 10, not 0!

When to use which:

• Default parameters - Most common, cleanest
• || - When you want to treat 0, "", false as "not provided"
• ?? - When 0 or false are valid values you want to keep

Understanding Data Flow

Props flow in one direction: from parent to child. This is called "one-way data flow" or "unidirectional data flow":

Props Flow: Parent → Child

App
Props:
theme: "dark"
UserCard
Props:
name: "Alice"
age: 25
Avatar
Props:
size: "large"
UserInfo
Props:
name: "Alice"
age: 25
Props
State
Click to expand/collapse
data-flow.jsx
function App() {
  const userName = "Alice"
  const userAge = 25
  
  // App passes props down to UserCard
  return <UserCard name={userName} age={userAge} />
}

function UserCard(props) {
  // UserCard receives props from App
  // UserCard passes some props down to Avatar
  return (
    <div>
      <Avatar name={props.name} />
      <p>Age: {props.age}</p>
    </div>
  )
}

function Avatar(props) {
  // Avatar receives props from UserCard
  return <img src={`/avatars/${props.name}.jpg`} alt={props.name} />
}

// Data flows: App → UserCard → Avatar

Props Are Read-Only!

You can never modify props inside a component:

props.name = 'New Name' ❌ Never do this!

Props are immutable. If you need to change data, you'll use state (which we'll learn about in later lessons).

Spreading Props

You can pass all properties of an object as props using the spread operator:

spread-props.jsx
function UserCard(props) {
  return (
    <div>
      <h2>{props.name}</h2>
      <p>{props.age}</p>
      <p>{props.email}</p>
    </div>
  )
}

function App() {
  const user = {
    name: 'Alice',
    age: 25,
    email: 'alice@example.com'
  }
  
  // Instead of:
  <UserCard name={user.name} age={user.age} email={user.email} />
  
  // You can use spread:
  <UserCard {...user} />
  
  // Both are equivalent!
}

Combining Spread with Additional Props

spread-with-props.jsx
function Button(props) {
  return <button {...props}>{props.children}</button>
}

function App() {
  const buttonProps = {
    className: 'btn',
    disabled: false
  }
  
  return (
    <div>
      {/* Spread existing props and add more */}
      <Button {...buttonProps} onClick={() => alert('Clicked!')}>
        Click Me
      </Button>
      
      {/* Props defined later override spread props */}
      <Button {...buttonProps} className="btn btn-primary">
        Override Class
      </Button>
    </div>
  )
}

⚠️ Spread Order Matters

<Button {...props} className="new" />
→ "new" overrides props.className

<Button className="new" {...props} />
→ props.className overrides "new"

Conditional Props

You can conditionally pass props based on conditions:

conditional-props.jsx
function Button({ isPrimary, isDisabled, onClick, children }) {
  return (
    <button
      className={isPrimary ? 'btn-primary' : 'btn-secondary'}
      disabled={isDisabled}
      onClick={onClick}
    >
      {children}
    </button>
  )
}

function App() {
  const isLoggedIn = true
  const hasPermission = false
  
  return (
    <div>
      {/* Pass props conditionally */}
      <Button
        isPrimary={isLoggedIn}
        isDisabled={!hasPermission}
        onClick={hasPermission ? handleClick : undefined}
      >
        {isLoggedIn ? 'Logout' : 'Login'}
      </Button>
    </div>
  )
}

Conditionally Including Props

include-props.jsx
function Link({ href, isExternal, children }) {
  return (
    
      href={href}
      // Only include these props if isExternal is true
      {...(isExternal && {
        target: '_blank',
        rel: 'noopener noreferrer'
      })}
    >
      {children}
    </a>
  )
}

<Link href="/about">About</Link>
// Renders: <a href="/about">About</a>

<Link href="https://example.com" isExternal>
  External
</Link>
// Renders: <a href="..." target="_blank" rel="noopener noreferrer">External</a>

Common Props Mistakes

1. Trying to Modify Props

mistake-modify-props.jsx
// ❌ NEVER modify props
function Counter(props) {
  props.count = props.count + 1  // Error! Props are read-only
  return <div>{props.count}</div>
}

// ✅ Props are read-only, use them as-is
function Counter(props) {
  return <div>{props.count}</div>
}

// ✅ For changes, you'll use state (covered in later lessons)
function Counter() {
  const [count, setCount] = React.useState(0)
  return <div onClick={() => setCount(count + 1)}>{count}</div>
}

2. Forgetting Curly Braces for Non-Strings

mistake-braces.jsx
// ❌ Wrong - age will be a string "25", not number 25
<User age="25" isActive="true" />

// ✅ Correct - use curly braces for non-strings
<User age={25} isActive={true} />

3. Passing Props to Wrong Component

mistake-wrong-component.jsx
function Parent() {
  return (
    <div>
      <Child name="Alice" age={25} />
    </div>
  )
}

// ❌ Wrong - props go to the div, not Child
function Child() {
  return (
    <div name="Alice" age={25}>  {/* These do nothing! */}
      Content
    </div>
  )
}

// ✅ Correct - receive props in function parameter
function Child(props) {
  return (
    <div>
      {props.name}, age {props.age}
    </div>
  )
}

4. Expecting Props in Wrong Format

mistake-format.jsx
function UserCard(props) {
  // ❌ Wrong - Expects props.user.name but receives props.name
  return <h2>{props.user.name}</h2>
}

<UserCard name="Alice" age={25} />

// ✅ Match your expectations with what's passed
function UserCard(props) {
  return <h2>{props.name}</h2>
}

// Or pass an object:
const user = { name: 'Alice', age: 25 }
<UserCard user={user} />

function UserCard(props) {
  return <h2>{props.user.name}</h2>
}

5. Using Props in Wrong Scope

mistake-scope.jsx
// ❌ Wrong - props doesn't exist outside component
const greeting = props.name  // Error!

function Greeting(props) {
  return <h1>Hello, {props.name}</h1>
}

// ✅ Correct - use props inside component
function Greeting(props) {
  const greeting = `Hello, ${props.name}`
  return <h1>{greeting}</h1>
}

Props Best Practices

1. Use Descriptive Prop Names

descriptive-names.jsx
// ❌ Unclear
<Button x="Save" y={handleSave} z={true} />

// ✅ Clear and descriptive
<Button label="Save" onClick={handleSave} isPrimary={true} />

2. Keep Related Props Together

group-props.jsx
// ❌ Hard to manage many related props
<User 
  firstName="Alice" 
  lastName="Johnson"
  email="alice@example.com"
  phone="123-456-7890"
  street="123 Main St"
  city="Boston"
  state="MA"
  zip="02101"
/>

// ✅ Group related props into objects
const user = {
  name: { first: 'Alice', last: 'Johnson' },
  contact: { email: 'alice@example.com', phone: '123-456-7890' },
  address: { street: '123 Main St', city: 'Boston', state: 'MA', zip: '02101' }
}

<User data={user} />

3. Validate Props (Optional)

validate-props.jsx
function Button(props) {
  // Basic validation
  if (typeof props.onClick !== 'function') {
    console.warn('Button: onClick prop should be a function')
  }
  
  if (!props.label) {
    console.warn('Button: label prop is required')
  }
  
  return <button onClick={props.onClick}>{props.label}</button>
}

// For production, consider using TypeScript or PropTypes library

4. Document Complex Props

document-props.jsx
/**
 * UserCard component displays user information
 * 
 * @param {Object} props
 * @param {string} props.name - User's full name
 * @param {number} props.age - User's age (must be positive)
 * @param {string} props.email - User's email address
 * @param {boolean} [props.isPremium=false] - Premium status (optional)
 * @param {Function} props.onEdit - Callback when edit button clicked
 */
function UserCard(props) {
  // Component implementation
}

Key Takeaways

  • Props are how you pass data from parent to child components
  • Props are passed like HTML attributes: <Component prop="value" />
  • Props are received as the first parameter in your function
  • Props are read-only - never modify them inside a component
  • String props use quotes, other types use curly braces
  • You can pass any data type: strings, numbers, booleans, arrays, objects, functions, JSX
  • Use default parameters or ||/?? for default values
  • Data flows one way: from parent to child (top to bottom)
  • Use spread operator {...props} to pass all properties at once
  • Boolean props can be shortened: isActive instead of isActive={true}
  • Props make components reusable with different data

What's Next?

You now know how to pass data between components using props! This makes your components flexible and reusable. But there's one special prop that deserves its own lesson: the children prop.

The children prop is unique - it lets you nest content inside components, just like you nest HTML elements. In the next lesson, you'll learn how to use children to create wrapper components, layouts, and build more flexible component architectures. Get ready to level up your component composition skills! 🎯

Learning how to pass data between React components with props!

Previous
Function Components
Next
Children Prop

Never Miss a New React Tutorial

Join 2,000+ developers learning React step-by-step. Get new tutorials, tips, and exclusive resources delivered to your inbox - completely FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

React Tutorials

0 of 42 completed

Your Progress0%

Topics

Getting Started

  • What is React?
  • React vs Vanilla JavaScript
  • Setting Up Your Environment
  • Your First React App

JSX Fundamentals

  • Introduction to JSX
  • JSX Expressions and Variables
  • Conditional Rendering
  • Lists and Keys
  • Styling in JSX

Components Basics

  • Function Components
  • Props
  • Children Prop
  • Props Destructuring
  • Component Composition

State Management

  • Introduction to State
  • useState Hook
  • State Updates and Re-renders
  • Multiple State Variables
  • State Best Practices

Events and Interactivity

  • Handling Events
  • Event Objects
  • Forms in React
  • Form Validation

Side Effects and Data

  • Introduction to useEffect
  • Data Fetching
  • Cleanup Functions
  • Dependency Arrays

Advanced Hooks

  • useRef Hook
  • useContext Hook
  • useMemo Hook
  • useCallback Hook

React Patterns

  • Custom Hooks
  • Higher-Order Components
  • Render Props Pattern

React Router

  • Introduction to React Router
  • Routes and Navigation
  • Dynamic Routes and Parameters

Best Practices

  • Component Organization
  • Performance Optimization
  • Error Handling
  • Testing React Components

Real World Project

  • Building a Complete App
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo