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.
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.
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.
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.
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.
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.
A component receiving props does not know where and how the information originates â it just sees a JavaScript object called props in React.
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 .
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.
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.
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.
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.
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.
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.
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.
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.
At some point, you are passing a lot of props down your component tree. Depending on the depth of the component tree, it can happen that many props are passed from a top level component to all the leaf components. Every component in between has to pass the props even though it may not be interested in the props. The problem is called prop drilling in React. There are a couple of solutions to overcome this âproblemâ (see component composition or slot pattern).
Another solution is Reactâs Context API which can be used to pass props implicitly down to component tree. Every component which is interested in the props passed by Reactâs Context API can consume them. All the other components donât need to consume them and thus they will never know about the props. Moreover, the components between the top level and the leaf components donât need to know about the props as well.
Previously you have got to know more about props and state in React. Sometimes there is one question which comes up for React beginners, but also for experienced React developers when implementing React components: How to set props to state? In case of the initial state, it is totally fine to derive it from the props. You can just use the incoming prop as initial state for a hook like Reactâs useState Hook:
Thatâs a common pattern in React. If the state needs to change when the incoming props change, it gets a bit more complicated. If you want to read more about the solution, check out the following guide.
There are a couple of pitfalls when passing props in React. Here I want to collect a list of these things in case someone stumbles upon them:
Sometimes you run into the problem that your React props are not being passed. Personally I ran into this issue several times when I forgot to use the curly braces for the props destructuring in my functional stateless components:
In this case, the onClick argument is the actual props. So you have to destructure it, so the first argument of the function, for accessing the onClick and children props.
Most often thatâs already the solution to the problem. If not, you should track down the prop from parent to child component by adding console.log(props) calls to your components. If you have a functional stateless component, you donât necessarily need to add an arrow function body to your component for putting the console.log() in between. Instead you can use this neat trick:
The console.log() always evaluates to undefined (a falsey value) and thus the component is still being rendered. Thatâs how you can easily get a logging for your props in between your input and output of your functional stateless component.
When rendering lists in React, you have to use a key prop identifying the element in the list. React uses the key for performance reasons, but also for keeping track of the element in case your list changes (e.g. due ordering, removing, adding of items). Thatâs why you should use a unique identifier which is associated to the rendered item.
So far, everything is alright with this code. However, sometimes you want to get the key prop in the child component.
Thatâs not working and you will also see a warning in your developer console log: â⦠key is not a prop. Trying to access it will result in undefined being returned. In this case, you have to pass a second prop when you want to get the key from the props.
In the end, thatâs the workaround to pass props (e.g. key) which are internally used by React and not passed to the child components.
Did you hear about styled components ? They can be used for styling your components in React. Rather than thinking about cascading style sheets as for HTML styles, you only style your components. So the style becomes more co-located to your components. In fact, in the case of styled components, the style becomes a React component:
The input element which is used to implement the Input styled component gets the value and onChange as props automatically. But what if you want to get props in a styled component to do something with them? Then you can add a string interpolation in the template literal and get the props in the inlined functionâs signature:
Basically thatâs how you pass props to styled components and how you get props in a styled component. If you havenât used styled components yet, you should give them a shot for styling your React components without thinking about CSS files.
I guess the article almost covered everything about passing props to React components. In the end, props arenât so difficult. They are read-only and enable you to pass data down the component tree. Everything else which makes React interactive is mostly state. So I hope this tutorial gave you a good overview about all the different usages of props in React.