Different React Props patterns and how to manage Data
Understanding React’s approach to data manipulation takes time. React has a different approach to data flow & manipulation than other frameworks, and that’s why it can be difficult at the beginning to understand some concepts like props, state, and so on.
To start using React you actually need to master a few important concepts. React's Props feature is one of them. Learn the concept of components, state, props, and hooks — and you know how to use React.
Here, briefly in my article I will summerise how props can be used on React component.
What is important to bear in mind is that in order to understand how props work, you need to have a general understanding of the concept of components.
When I started learning React, I was curious about what are props and how they actually work.
👉 Props stand for properties and is a special keyword in React
👉 Props are being passed to components like function arguments
👉 Props can only be passed to components in one way (parent to child)
👉 Props data is immutable (read-only)
🛑 In JavaScript, we can access object elements with dot(.) notation.
🛑 In react we can render a property with an interpolation
const ChildComponent = (props) => {
return <p>{props.text}</p>;
};
🤖 React is a component-based
library that divides the UI into little reusable pieces. In some cases, those components need to communicate (send data to each other) and the way to pass data between components is by using props.
“Props” is a special keyword in React, which stands for properties and is being used for passing data from one component to another.
But the important part here is that data with props are being passed in a uni-directional flow. (one way from parent to child)
Furthermore, props data is read-only, which means that data coming from the parent should not be changed by child components.
🚀 React props can be passed conditionally
Props that are passed to components can be thought of like arguments that are passed to a function.
If prop values are not passed a certain component, an error will not be thrown. Instead, within the component that prop will have a value of undefined.
export default function App(){
return (
<MyComponent title"My React basics!"/>
);
}
function MyComponent(props) {
return (
<h1>My React basics{props.tittle}!</h1
)
}
So Props in react can be used in the following ways:
👉 Firstly, define an attribute and its value(data)
👉 Then pass it to child component(s) by using Props
👉 Finally, render the Props Data
If you would like to be alerted to when a value is not passed as a prop to a component, you can use a tool like prop-types or TypeScript using these tools.
🤔 React props passed with just their name have a value of true
Every prop must be given an associated value that is provided after the equals operator.
But what happens when we don't provide that equals operator as well as a value?
If you just provide the proper name on a component with nothing else, you pass a boolean value of true for that prop to the component. There is no need to write that a prop is equal to true.
Instead, you can just include the prop value, and it will be given the boolean value true when you use it in a component to which you pass it.
export default function App(){
return (
<MyComponent showTitle={true} />
);
function MyComponent(props) {
if (props.showTitle) {
return <h1>My React basics<h1/>
}
return null;
React props can be accessed as an object or destructured
There are a couple of patterns we can use for accessing prop values in our components.
Props
can be accessed as an entire object
which is usually called "props"
. Or they can be destructured, since props will always be an object, into separate variables.
If you have a lot of props that you're passing down to your component, it may be best to include them on the entire props object and access them by using props.propName
.
However, if you only have a few props that you're passing down to your component, you can immediately destructure them within the parameters of your function component.
export default function App(){
return (
<MyComponent showTitle title="My react basics" />
);
}
function MyComponent(props) {
if (props.showTitle) {
return <h1>{title}<h1/>
}
return null;
}
Actually ES6 object destructuring can be used to include a set of curly braces within the function component's parameters, and immediately grab the properties off of the object, as well as declare them as separate variables.
This cuts down the code and eliminates the need to use props.propName
to get each props value.
React components can be passed as props (including children)
👉 The props are very flexible, and if we don't pass them to a component, an error will not be thrown.
This flexibility is also extended to what we can pass as a prop. Not only can JSX elements be passed as props to components, but we can also pass other components as props.
In fact, there is a special type of prop that is automatically provided on the props object called children
.
🛑 We receive any children for a given component if any components or elements are passed between the opening and closing tags of that component.
👉 The children prop allows us to compose our components in powerful ways.
This is especially helpful when we need to wrap one component around another, such as for styling, or to pass more component data to the children components to give two examples:
Children props
are very helpful when you want to make a generic layout component
and give the same layout to all of the components that are passed as children.
Also, children are useful when you want to place a context provider from React context around your component tree to easily provide what is placed on context provider to all of its child components so they can receive the same data.
Anything can be passed as a prop in React (especially functions)
Any normal JavaScript value can be passed as props as well, including functions.
There are some powerful patterns which have emerged, due to the ability to pass functions as props. A very common pattern is passing a function down to a child component as a prop, which can update the parent component's state, and then calling it within that child component.
export default function App() {
const [title, setTitle] = React.useState('My React basics')
return(
<MyComponent title={title setTitle={setTitle}/>
);
}
function MyComponent({ title, setTitle }) {
function updateTitle(){
setTitle("My react basics")
}
return <h2 onClick={updateTitle}>{title}</>
}
Using this function that is passed down to update the parent's state and perform a function is called "lifting state up". Additionally, there are other patterns, such as the render props pattern, which also involve passing a function down to a child component to then be called back and perform some cross-component function.
Update a React prop's value with state
🛑 Props cannot be directly updated.
To pass a prop value to a component, we cannot within that function component attempt to immediately change that prop's value.
Prop values must be pure values. In other words, they cannot be mutated or changed directly. In React if we want to change values over time, the appropriate means to do so is with
state
.
If we would like to pass in a prop value to a component and change it later on, we can give it to a stateful React hook to store that value as a variable. Then we can update it later on using the appropriate setter function. We can do so with the useState
hook or the useReducer
hook.
React props can be spread in individually
What if we have an object whose properties we want to pass down as individual prop values?
This object has a lot of properties, however. Do we need to manually create individual props and set the prop to object.propertyName?
No – instead of doing that for every property, we can very easily take the object and spread its properties down to a component as individual prop values using the object spread operator {...myPropObject}
.
import React from 'react';
export default function App() {
const data = {
title:"my title",
description:"my description",
button: "learn more"
}
return (
<MyComponent{...data}/>
);
}
function MyComponent({title, description, button})
return(
<div>
<h1>{title}</h1>
<p>{description</p>
<button>{button}<button/>
</div>
)
}
return <h2 onClick={updateTitle}>{title}</>
}
When working with large objects with a lot of properties we want to pass as individual props to a component.
React props can be given a default value if none is provided
What if passing down a prop to one instance of a component, but do not passing that prop
to another instance of it?
What to do to give a default value to a prop instead of just the value undefined
if no prop value is passed to it?
🛑 If using destructuring to access that prop
within the function component, the equals operator can be used to give it a default value. So if no prop value is passed for that prop, we can use the equals operator next to it and set it to a better default value.
Setting a default value is very important because the normal default value for a prop is undefined. This can help us avoid errors that may result from our expected prop value not being there.
React props can be renamed to avoid errors
What happens if there is a naming conflict with one of our props?
What if we use a prop name across many of the components and we see that there is another value within the component that has the same variable name?
Instead of having to go around and rename all of our prop values on all of our instances of our components, a colon after that prop name can be used, if we're destructuring it, to give it an alias. So to avoid naming conflict and errors give it a different name just in that instance.
🛑 Don't attempt to destructure React props multiple times
If we are destructuring an object from our props object, be aware that it is possible to destructure that prop even further into its constituent properties.
However, it is not generally recommended to do so unless being confident that that object will always have those properties.
If one of those properties is missing and you attempt to destructure it multiple levels deep, it can give an error when you're trying to access a property that doesn't exist.
How to render the data coming from parent components?
Each ChildComponent
renders its own prop data
. So in the snippet bellow is shown how Props
can be used for passing data and converting static components into dynamic ones.
class ParentComponent extends Component {
render() {
return (
<h1>
The parent component.
<ChildComponent text={"the 1st child"} />
<ChildComponent text={"the 2nd child"} />
<ChildComponent text={"the 3rd child"} />
</h1>
);
}
}
Passing props is simple. Like we pass arguments to a function, we pass props into a React component and props bring all the necessary data. Arguments passed to a function:
const addition = (firstNum, secondNum) => {
return firstNum + secondNum;
};
Arguments passed to a React component:
const ChildComponent = (props) => {
return <p>the 1st child!</p>;
};
👉
Props
actually are arguments passed into React components.
Happy coding! 🌴 💻