Props (properties) pass data from parent to child components. Props are read-only — never modify them inside the child.

Passing Props

  function Greeting({ name, age }) {
    return (
        <div>
            <h1>Hello, {name}!</h1>
            <p>You are {age} years old.</p>
        </div>
    );
}

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

Destructuring Props

  // In parameter
function UserCard({ name, email, avatar }) {
    return (
        <div>
            <img src={avatar} alt={name} />
            <h2>{name}</h2>
            <p>{email}</p>
        </div>
    );
}

// Or inside function
function UserCard(props) {
    const { name, email } = props;
    return <h2>{name}</h2>;
}
  

Default Props

  function Button({ label = 'Click me', variant = 'primary', onClick }) {
    return (
        <button className={`btn btn-${variant}`} onClick={onClick}>
            {label}
        </button>
    );
}

<Button />                    // "Click me", primary
<Button label="Submit" />     // "Submit", primary
<Button variant="danger" label="Delete" />
  

Passing Functions as Props

  function SearchBar({ onSearch }) {
    const [query, setQuery] = useState('');

    const handleSubmit = (e) => {
        e.preventDefault();
        onSearch(query);
    };

    return (
        <form onSubmit={handleSubmit}>
            <input value={query} onChange={e => setQuery(e.target.value)} />
            <button type="submit">Search</button>
        </form>
    );
}

// Parent
function App() {
    const handleSearch = (query) => console.log('Searching:', query);
    return <SearchBar onSearch={handleSearch} />;
}
  

Spread Props

  function Input({ label, ...inputProps }) {
    return (
        <div>
            <label>{label}</label>
            <input {...inputProps} />
        </div>
    );
}

<Input label="Email" type="email" placeholder="[email protected]" required />
  

Props Are Immutable

  function BadComponent(props) {
    props.name = 'Changed'; // ERROR — never mutate props
    return <h1>{props.name}</h1>;
}
  

If you need to change data, use state (next chapter).

PropTypes (Optional)

  npm install prop-types
  
  import PropTypes from 'prop-types';

function User({ name, age, email }) {
    return <div>{name}, {age}</div>;
}

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

User.defaultProps = {
    age: 0
};
  

With TypeScript, use interfaces instead of PropTypes (see TypeScript with React).

Props flow down the component tree — for sharing data across distant components, use Context or state management libraries.