Runnable lesson · press Try it on the examples to edit and run them here.
Writing props.name, props.age and props.city again and again gets noisy. JavaScript’s destructuring lets you pull values out in one step. If it is new to you, read Object Destructuring first.
In the parameter list
The most common style takes the props apart right in the function signature:
function Person({ name, age, city }) {
return <p>{name}, {age}, {city}</p>;
}
function App() {
return <Person name="Ada" age={36} city="London" />;
}
{ name, age, city } says: “my first argument is an object; give me these three keys as variables”. It also documents the component: you can see its props at a glance.
Inside the function
Sometimes you want the whole props object too, for example to pass it on. Then destructure in the body:
function Person(props) {
const { name, age } = props;
return <p>{name}, {age}</p>;
}
function App() {
return <Person name="Ada" age={36} />;
}
Defaults and renaming
function Person({ name = "Guest", age: years = 18 }) {
return <p>{name}, {years}</p>;
}
function App() {
return <Person />;
}
name = "Guest"is a default value.age: yearsrenames: the prop isage, the local variable isyears.
Rest: collect the remaining props
The rest syntax ...others gathers every prop you did not name. It is useful for forwarding extra attributes to an element:
function TextInput({ label, ...inputProps }) {
return (
<label>
{label}{" "}
<input {...inputProps} />
</label>
);
}
function App() {
return <TextInput label="Search" aria-label="Search" placeholder="Type here" maxLength={20} />;
}
label is used by the component; placeholder, maxLength and aria-label are passed straight to the <input>. This pattern makes small wrapper components feel like native elements.
Nested objects
You can destructure inside destructuring, but do not overdo it:
function Person({ user: { name, address: { city } } }) {
return <p>{name} lives in {city}</p>;
}
function App() {
const user = { name: "Ada", address: { city: "London" } };
return <Person user={user} />;
}
If it is hard to read, take the object as one prop and destructure in the body with simple steps. Also remember that destructuring address fails if address can be undefined.
Common mistakes
- Destructuring a prop that was not passed gives
undefined; provide defaults. - Using
props.xand{ x }in the same component makes the reader wonder which is which. Pick one style. - Giving a component too many props. If the signature has 12 names, the component probably does too much.
Key points
- Destructure in the parameter list:
function Card({ title, body }). - Use
=for defaults,:to rename and...restto forward the remaining props. - Keep nested destructuring shallow.