How to use Props in React
Everyone who is new to React is confused by React props, because they are never mentioned in any other framework, and rarely explained on their own. They are one of the early things you will learn in React after grasping React's JSX syntax. Essentially React component props are used to pass data from component to component. In this tutorial, I want to explain props in React in greater detail by going step by step through React props examples.
REACT COMPONENT PROPS BY EXAMPLE
Normally you start out with React's JSX syntax for rendering something to the browser when learning about React. Basically JSX mixes HTML with JavaScript to get the best of both worlds:
A bit later you will split out your first React function component:
A common question followed by this refactoring: how to pass the data from one React component to another component? After all, the new component should render a dynamic greeting
, not the static greeting
that is defined within the new component. It should behave like a function which I can pass parameters after all.
Entering React props -- where you can pass data from one component to another in React -- by defining custom HTML attributes to which you assign your data with JSX's syntax:
Since you will always find the props as first argument in the function signature of a function component, which is just the JavaScript object holding all data passed from component to component, you can destructure the props early. One would call it React Props Destructuring:
As you have seen, props enable you to pass values from one component to another component down the component tree. In the previous example, it was only a string variable. But props can be any JavaScript data type from integers over objects to arrays. Via props you can even pass React components as well, which you will learn about later.
For what it's worth, you can also define the props inline without declaring a variable before:
In the case of a JavaScript string, you can pass it as props inside double quotes (or single quotes) too:
But you can also pass other JavaScript data structures with these kind of inline props. In case of JavaScript objects, it can be confusing for React beginners, because you have two curly braces: one for the JSX and one for the JavaScript object notation:
When declaring the data as a proper JavaScript object, it gets more readable:
Most React beginners notice this when passing a style object to a style attribute to a native HTML element in React for the first time:
Basically that's how props are passed from component to component in React. As you may have noticed, props are only passed from top to bottom in React application's component hierarchy. There is no way to pass props up to a parent component from a child component. We will revisit this caveat later in this tutorial.
It's also important to note that React's props are read only (immutable). As a developer, you should never mutate props but only read them in your components. You can derive new values from them though (see computed properties later). After all, props are only used to pass data from a parent to a child component React. Essentially props are just the vehicle to transport data down the component tree.
REACT PROPS VS. STATE
Passing props from component to component in React doesn't make components interactive, because props are read-only and therefore immutable. If you want interactive React components, you have to introduce stateful values by using React State. Usually state is co-located to a React component by using React's useState Hook:
In the last example, the App component uses a stateful value called isShow
and a state updater function to update this state in an event handler. Depending on the boolean state of isShow
, the parent component either renders its child component or not by using a conditional rendering.
The example shows how state is different from props: While props are just a vehicle to pass information down the component tree, state can be changed over time to create interactive user interfaces. The next example shows how state can become props when it is passed to a child component. Even though the state becomes props in the child component, it can still get modified in the parent component as state via the state updater function. Once modified, the state is passed down as "modified" props:
In other words one could say that the value (state) in the vehicle (props) has changed. The child component doesn't care whether the value inside the props are stateful values -- it just sees them as props which come from the parent component. Since every state change in a component (here the parent component) causes a re-render of this and all child components, the child component just receives the updated props in the end.
In conclusion, every time the state changes, the rendering mechanism of the affected component and all its child components get triggered. That's how the whole component tree becomes interactive, because after all, stateful values (state) are passed as props to child components, and once the state in a component changes, which may be passed as props to the child components, all re-rendering child components use the new props.
HOW TO PASS PROPS FROM CHILD TO PARENT COMPONENT
Since props can only be passed from parent to child components, how can a child component communicate with its parent component? This a common question for React beginners once they learned about props in React and the answer for it is brief: there is no way to pass props from a child to a parent component.
Let's revisit the previous example, but this time with a new reusable component called Button for the previously implemented display/hide toggle feature:
So far, the new Button component manages its own co-located state. Since the Button component manages the isShow
stateful value, there is no way to pass it up as props to the parent component where it is needed for the conditional rendering of the Welcome component. Because we do not have access to the isShow
value in the App component, the application breaks. To fix this, let's enter how to lift state in React:
The application works again. The important ingredient: the App component passes down a function in the props to the Button component. The function, named callback handler in React (because it is passed from component to component via props and calls back to the origin component), is used for the click handler in the Button component.
Continue Reading: Learn about handlers, callback handlers, and inline handlers in React
The Button doesn't know the business logic of the function though, only that it has to trigger the function when the button gets clicked. Above in the App component, the state is changed when the passed function is called, and therefore the parent component and all its child components re-render.
Continue Reading: Learn more about Lifting State in React
As said, there is no way passing props from a child to a parent component. But you can always pass functions from parent to child components, whereas the child components make use of these functions and the functions may change the state in a parent component above. Once the state has changed, the state is passed down as props again. All affected components will render again.
REACT PROPS ARE JUST THE COMMUNICATION CHANNEL
A component receiving props does not know where and how the information originates -- it just sees a JavaScript object called props in React.
Where: The props can originate in the parent component or somewhere above the component hierarchy.
How: The information can be stateful or something else.
For example, props can be passed not only from a parent to a child component, but also from ancestor components to descendant components:
Both the Headline and the Description components do not know whether the information originates in the Welcome or App component. The same applies if greeting
would become a stateful value in the App component by using React's useState Hook. Then the stateful greeting
would become just text
-- a property in the Welcome component's props -- which passes it down to its child components.
Last but not least, have a closer look at the Welcome component from the last example. It passes a title prop to the Headline component, but doesn't use just the text.title
but creates a new string from it. Without modifying the props, the component uses the title
property to derive a new value from it. This principle is called computed properties in React.
REACT PROPS DESTRUCTURING
Previously you have briefly learned about props destructuring in React and have used it throughout all the previous props examples. Let's quickly recap it here. Props in React is essentially all data that is passed from a parent to a child component. In a child component, props can be accessed in the function signature as parameter:
If we understand props as vehicle to communicate from parent to child component, we often don't want to use the vehicle directly, but rather only want to use what's in there. Hence we can destructure the incoming argument:
Because we can destructure a JavaScript object in a function signature too, we can leave out the intermediate variable assignment:
If multiple props are passed to a child component, we can destructure all of them:
However, there are occasions where we actually keep props as the object. So let's discuss them in the next sections.
REACT SPREAD PROPS
A strategy for passing all properties of an object to a child component is using the JavaScript spread operator. JavaScript's spread operator in React is a useful power feature and you can read people referring to it as the React ...props syntax even though it is not really a React feature but just a thing coming from JavaScript.
The props spreading can be used to spread a whole object with key value pairs down to a child component. It has the same effect as passing each property of the object property by property to the component. For example, sometimes you have a component in between which does not care about the props and just passes them along to the next component:
Be aware that the spreaded attribute/value pairs can be overridden as well:
If the props spreading comes last, all the previous attributes get overridden if they are present in the props:
After all, the spread operator can always be used to assign each key/value pair of an JavaScript object conveniently to a attribute/value pair of the HTML element.
REACT REST PROPS
The JavaScript rest destructuring can be applied for React props too. Let's walk through an example for the rest props. First, we define a button with an inline handler which increases the state of a number. The button got already extracted as a reusable component:
A HTML button can receive lots of attributes. For example, it's not far fetched that a button is disabled for certain scenarios. So let's provide the Button component with this new prop:
Over time, there will be more and more props that we want to pass to the button and therefore the Button component's function signature will grow in size. We could continue doing it this way, being explicit about every prop the Button component receives. However, we could also use JavaScript's rest destructuring which collects all the remaining properties from an object which didn't get destructured:
Making this even more convenient for the implementation of the Button component, we can use JavaScript's spread operator for spreading the rest props to the button HTML element. This way, anytime we pass a new prop to the Button component and don't destructure it explicitly, it gets automatically assigned to the button HTML element:
Little unrelated gotcha at the end of this section: the next example shows how passing a boolean as an inline value of true
can be written as a shorthand, because the attribute gets evaluated to true in the child component this way:
In conclusion, props spreading and rest props can help tremendously to keep the implementation details in a readable size.
REACT PROPS WITH DEFAULT VALUE
In some cases, you may want to pass default values as props. Historically the best approach to it was using JavaScript's logical OR operator.
Which you could also inline as prop:
However, with modern JavaScript you can use the default value for the prop when using destructuring:
That's it for defaulting to a fallback prop in React which is yet another tool in your toolchain to write effective and efficient React.
REACT'S CHILDREN PROP
The children prop in React can be used for composing React components into each other. Because of this feature, you can put JavaScript primitives or JSX between the opening and closing element's tags:
In this case, only a string is put in between of the element's tags. Then in the child component, you can make use of everything which is in between the tags by using React's children prop. For instance, you can just render the content of the children prop like it is done in this example. In the following sections, you will see how the children prop can be used as a function too.
HOW TO PASS COMPONENTS AS PROPS
Before you have learned about React's children prop which allows you also to pass HTML/React element(s) to components as props:
However, what if you want to pass more than one React element and place them at different positions? Then again you don't need to use the children prop, because you have only one of them, and instead you just use regular props:
Often this approach is used when having a surrounding layout component which takes multiple components as content with props. Now you can exchange the Avatar or Biography components dynamically with other components such as:
Many people refer to this as slot pattern in React. You can find a working minimal project on GitHub. And again, that's how composition in React shines. You don't need to touch the Profile component. Moreover, you don't need to pass props - in this case the user - multiple levels down the component tree, but rather pass it to the slotted components.
CHILDREN AS A FUNCTION
The concept of children as a function or child as a function, also called render prop, is one of the advanced patterns in React (next to higher-order components). The components which implement this pattern can be called render prop components.
Continue Reading: Learn Render Prop Components from 0 to 1
First, let's start with the render prop. Basically it is a function passed as prop. The function receives parameters (in this case the amount), but also renders JSX (in this case the components for the currency conversion).
Second, refactor the whole thing from having arbitrary render prop to having a more specific children as a function:
That's essentially everything to distinguish between a render prop or a more specific children as a function (which at its core is a render prop too). The former is passed as a arbitrary prop and the latter is passed as a children prop. You have seen before that functions can be passed as callback handlers (e.g. button click) to React components, but this time the function is passed to actually render something whereas the responsibility for what to render is partially moved outside of the render prop component while the props are provided by the render prop component itself.
You can find a working minimal project on GitHub. And again, if you had any problems following the last examples, check the referenced article, because this guide doesn't go into detail for render prop components in React.
Last updated