How we pass data from parent component to child component (DOWN the component tree)
- essential tool to configure and customize components
- parents can control how child components look and work
- simply stands for property
- Anything can be passed as props (single values, arrays, objects, functions, even other components!)
Props are Immutable
Components have to be pure functions in terms of props and state
- Read only! (one of react’s strict rules)
- Data that is coming from the outside (parent component). CANNOT BE MODIFIED BY THE CHILD COMPONENT, can be only be updated by the parent component.
- If you need to mutate props, you actually need state
- Why is it immutable?
- props are just objects. so if u change the props object in your component, it will affect the parent, creating side effects (not pure) (this is just how objects work in js)
- in js, when you copy an object and mutate the copy, the original object will also be mutated!
- a side effect is create when you mutate some data located outside of the current function
- props are just objects. so if u change the props object in your component, it will affect the parent, creating side effects (not pure) (this is just how objects work in js)
One way data flow
- React uses one-way data flow
- Data can only be passed from parent to child components (which happens using props), but NEVER the opposite way!
- TOP to BOTTOM in a component tree
- reasons
- makes the applications more predictable and easier to understand
- makes applications waaaay easier to debug (as we have more control over the data)
- less performant
Steps and Examples
- Pass the props into the component
- Receive the props in the component
function Menu() {
return (
<main className="menu">
<h2>Our Menu</h2>
<Pizza index={0} photoLink="pizzas/spinaci.jpg" />
</main>
);
}
- Accepts a props parameters
- the order which you pass in the props are completely irrelevant
function Pizza(props) {
return (
<div>
<img src={props.photoLink} alt="Pizza spinaci" />
<h3>{pizzaData[props.index].name}</h3>
<p>{pizzaData[props.index].ingredients}</p>
</div>
);
}
- props object is
{index:0, photoLink:"Pizza spinaci"}
. we can access the properties
Destructuring 1
- Destructures individual properties (
index
,photoLink
) from props.
function Pizza({ index, photoLink }) {
return (
<div>
<img src={photoLink} alt="Pizza spinaci" />
<h3>{pizzaData[index].name}</h3>
<p>{pizzaData[index].ingredients}</p>
</div>
);
}
Destructuring 2
- Destructures pizzaObj as a whole, but doesn’t destructure its internal properties
// in the menu
<Pizza pizzaObj={pizza} />
// component
function Pizza({ pizzaObj }) {
return (
<div>
<img src={pizzaObj.photoLink} alt="Pizza spinaci" />
<h3>{pizzaObj.name}</h3>
<p>{pizzaObj.ingredients}</p>
</div>
);
}
Rendering lists
Usually we pass in the entire elements and extract the necessary info in the component
- using the map function in JS
- We do this when we have an array and we want to create a component for each element in the array
function Menu() {
return (
<main className="menu">
<h2>Our Menu</h2>
{pizzaData.map((pizza) => {
return <Pizza pizzaObj={pizza} />;
})}
</main>
);
}
// ======= METHOD 1 =======
function Pizza(props) {
return (
<div className="pizza">
<img src={props.pizzaObj.photoName} alt="Pizza spinaci" />
<div>
<h3>{props.pizzaObj.name}</h3>
<p>{props.pizzaObj.ingredients}</p>
<span>{props.pizzaObj.price + 3}</span>
</div>
</div>
);
}
// ======= METHOD 2 =======
function Pizza({ pizzaObj }) {
return (
<div className="pizza">
<img src={pizzaObj.photoName} alt="Pizza spinaci" />
<div>
<h3>{pizzaObj.name}</h3>
<p>{pizzaObj.ingredients}</p>
<span>{pizzaObj.price + 3}</span>
</div>
</div>
);
}
- Referring to
pizzaData
within thePizza
component - Passing the
pizza
object directly as a prop to thePizza
component