Props are read-only
A hard rule: a component must never change its props. Props flow downward from parent to child, and the child treats them as read-only input. This is what makes components predictable: same props in, same UI out, every time. Functions with that property are called pure, an idea you met with map callbacks in Advanced JavaScript.
function Price({ amount }) { amount = amount * 1.1; // WRONG: mutating input return <p>{amount}</p>; } function Price({ amount }) { const withTax = amount * 1.1; // RIGHT: derive a new value return <p>{withTax}</p>; }
Deriving new values from props is normal and encouraged. Reassigning or mutating the props themselves is not.
If a child needs to change data, the parent passes down a function prop and the child calls it. We will build that pattern in Unit 4 with state, and again in Unit 8 when we lift state up.
Default values
A component's props form its contract: which inputs it accepts, which are required, what happens when one is missing. Destructuring defaults (Advanced JavaScript again) handle the missing case cleanly:
function Button({ label = "Click me", kind = "default" }) { return <button className={kind}>{label}</button>; } <Button label="Save" kind="primary" /> // uses both <Button label="Cancel" /> // kind falls back <Button /> // both fall back
Defaults make components safe to use with partial props and document the contract right in the signature.
Code exercise · javascript
Your turn. Give Button default values, label defaults to "Click me" and kind defaults to "default", so all three calls print the expected output.
Quiz
Spot the bug: ```jsx function Discount({ price }) { price = price - 5; return <p>Now only {price}</p>; } ```