React Props - Complete Guide

React Props - Complete Guide

React props (short for properties) are how components talk to each other. They let you pass data from a parent component to a child component, making your components reusable and dynamic.

What Are Props?

Props are like function arguments in React. When you create a component, you can pass data to it as props. The component can then use that data to render different content.

Think of props as configuration options for your components. You give a component some props, and it uses those props to decide what to display.

Basic Props Usage

Passing Props

Here’s how you pass props to a component:

// Parent component
function App() {
  return <Welcome name="Alice" age={25} />;
}

// Child component that receives props
function Welcome(props) {
  return <h1>Hello, {props.name}! You are {props.age} years old.</h1>;
}

Destructuring Props

You can make your code cleaner by destructuring props directly in the function parameters:

// Instead of this
function Welcome(props) {
  return <h1>Hello, {props.name}!</h1>;
}

// Do this
function Welcome({ name, age }) {
  return <h1>Hello, {name}! You are {age} years old.</h1>;
}

Types of Props

String Props

String props are the most common type. You pass them in quotes:

function Button({ text }) {
  return <button>{text}</button>;
}

function App() {
  return <Button text="Click me!" />;
}

Number Props

For numbers, use curly braces:

function UserProfile({ userId }) {
  return <div>User ID: {userId}</div>;
}

function App() {
  return <UserProfile userId={123} />;
}

Boolean Props

Boolean props control component behavior:

function Button({ disabled, children }) {
  return <button disabled={disabled}>{children}</button>;
}

function App() {
  return (
    <div>
      <Button disabled={false}>Active Button</Button>
      <Button disabled={true}>Disabled Button</Button>
    </div>
  );
}

Array Props

Pass arrays to display lists of data:

function TodoList({ items }) {
  return (
    <ul>
      {items.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
}

function App() {
  const todos = ["Learn React", "Build projects", "Get hired"];
  return <TodoList items={todos} />;
}

Object Props

Objects are great for passing related data together:

function UserCard({ user }) {
  return (
    <div>
      <h2>{user.name}</h2>
      <p>Email: {user.email}</p>
      <p>Role: {user.role}</p>
    </div>
  );
}

function App() {
  const userData = {
    name: "John Doe",
    email: "[email protected]",
    role: "Developer"
  };
  
  return <UserCard user={userData} />;
}

Function Props

You can pass functions as props to handle events:

function Counter({ count, onIncrement, onDecrement }) {
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={onIncrement}>+</button>
      <button onClick={onDecrement}>-</button>
    </div>
  );
}

function App() {
  const [count, setCount] = useState(0);
  
  const increment = () => setCount(count + 1);
  const decrement = () => setCount(count - 1);
  
  return (
    <Counter 
      count={count} 
      onIncrement={increment} 
      onDecrement={decrement} 
    />
  );
}

Props Best Practices

1. Use Descriptive Names

Make your prop names clear and descriptive:

// Good
<UserCard userName="Alice" userAge={25} />

// Bad
<UserCard n="Alice" a={25} />

2. Provide Default Values

Use default props or default parameters:

// Using default parameters
function Button({ text = "Click me", type = "primary" }) {
  return <button className={`btn-${type}`}>{text}</button>;
}

// Or using defaultProps (class components)
class Button extends React.Component {
  static defaultProps = {
    text: "Click me",
    type: "primary"
  };
}

3. Validate Props

Use PropTypes for runtime validation:

import PropTypes from 'prop-types';

function UserCard({ name, age, email }) {
  return (
    <div>
      <h2>{name}</h2>
      <p>Age: {age}</p>
      <p>Email: {email}</p>
    </div>
  );
}

UserCard.propTypes = {
  name: PropTypes.string.isRequired,
  age: PropTypes.number,
  email: PropTypes.string.isRequired
};

UserCard.defaultProps = {
  age: 0
};

4. Keep Components Small

Pass only the props a component actually needs:

// Instead of passing the whole user object
function UserAvatar({ user }) {
  return <img src={user.avatar} alt={user.name} />;
}

// Pass only what's needed
function UserAvatar({ avatar, name }) {
  return <img src={avatar} alt={name} />;
}

Props vs State

It’s important to understand the difference between props and state:

  • Props: Read-only data passed from parent to child
  • State: Mutable data managed within a component
function ParentComponent() {
  const [message, setMessage] = useState("Hello from parent");
  
  return <ChildComponent message={message} />;
}

function ChildComponent({ message }) {
  // Can't modify props directly
  // message = "New message"; // This won't work!
  
  return <p>{message}</p>;
}

Spreading Props

Sometimes you want to pass all properties of an object as props:

const userProps = {
  name: "Alice",
  age: 25,
  email: "[email protected]"
};

// Instead of this
<UserCard name={userProps.name} age={userProps.age} email={userProps.email} />

// Do this
<UserCard {...userProps} />

Be careful when spreading props - only pass what the component actually needs.

Children Prop

React automatically passes children as a special prop:

function Card({ children, title }) {
  return (
    <div className="card">
      <h2>{title}</h2>
      <div className="card-content">
        {children}
      </div>
    </div>
  );
}

function App() {
  return (
    <Card title="Welcome">
      <p>This is the card content.</p>
      <button>Click me</button>
    </Card>
  );
}

Render Props Pattern

Sometimes you pass a function as a prop that returns JSX:

function DataFetcher({ url, render }) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    fetch(url)
      .then(response => response.json())
      .then(data => {
        setData(data);
        setLoading(false);
      });
  }, [url]);
  
  if (loading) return <div>Loading...</div>;
  
  return render(data);
}

function App() {
  return (
    <DataFetcher 
      url="/api/users"
      render={data => (
        <div>
          <h2>Users</h2>
          {data.map(user => (
            <p key={user.id}>{user.name}</p>
          ))}
        </div>
      )}
    />
  );
}

Common Props Patterns

1. Configuration Props

Use props to configure component behavior:

function Modal({ isOpen, onClose, size = "medium", showCloseButton = true }) {
  if (!isOpen) return null;
  
  return (
    <div className={`modal modal-${size}`}>
      {showCloseButton && (
        <button onClick={onClose} className="close-button">×</button>
      )}
      <div className="modal-content">
        {/* Modal content here */}
      </div>
    </div>
  );
}

2. Styling Props

Pass styling information through props:

function Button({ variant = "primary", size = "medium", children }) {
  const className = `btn btn-${variant} btn-${size}`;
  
  return <button className={className}>{children}</button>;
}

function App() {
  return (
    <div>
      <Button variant="primary" size="large">Big Primary Button</Button>
      <Button variant="secondary" size="small">Small Secondary Button</Button>
    </div>
  );
}

3. Conditional Props

Use props to control what gets rendered:

function Alert({ type, message, showIcon = true }) {
  const icons = {
    success: "✓",
    error: "✗",
    warning: "⚠",
    info: "ℹ"
  };
  
  return (
    <div className={`alert alert-${type}`}>
      {showIcon && <span className="alert-icon">{icons[type]}</span>}
      <span className="alert-message">{message}</span>
    </div>
  );
}

Props and Component Reusability

Good prop design makes components highly reusable:

// Bad - Hard to reuse
function WelcomeMessage() {
  return <h1>Welcome, Alice!</h1>;
}

// Good - Highly reusable
function WelcomeMessage({ name, greeting = "Welcome" }) {
  return <h1>{greeting}, {name}!</h1>;
}

// Can be used in many ways
<WelcomeMessage name="Alice" />
<WelcomeMessage name="Bob" greeting="Hello" />
<WelcomeMessage name="Carol" greeting="Good morning" />

Summary

Props are fundamental to React development. Remember these key points:

  • Props are read-only and passed from parent to child
  • Use descriptive prop names
  • Provide default values when appropriate
  • Validate props with PropTypes
  • Keep components focused and pass only necessary props
  • Use the children prop for flexible content composition

Mastering props will make you a better React developer and help you build more maintainable, reusable components.


External Resources:

Related Tutorials:

Last updated on