Pass Props Back Up to Parent React Native
As you learn how to develop web applications using React, you will inevitably come across the concept of props. Understanding the way props work is essential to mastering React, but to grasp the concept fully is no easy thing.
Props in React: an introduction
Props stands for "properties," and they are used in a React application to send data from one React component to another React component. Let's take a look at the example code below. Here we have a single React component rendering a string:
import React, { Component } from "react"; import ReactDOM from "react-dom"; class App extends Component { render(){ return <div>Hello, World!</div> } } ReactDOM.render(<App />, document.getElementById("root"));
Now here's how you add props into theApp
component: right beside the call to the App component onReactDOM.render
, type a random property and assign it a value. I will create aname
property and assign it as"Nathan"
:
import React, { Component } from "react"; import ReactDOM from "react-dom"; class App extends Component { render(){ return <div>Hello, World!</div> } } ReactDOM.render(<App name="Nathan" />, document.getElementById("root"));
And with that, theApp
component now has a props calledname
; you can call on it from the class usingthis
. Let me show you how I greet myself:
import React, { Component } from "react"; import ReactDOM from "react-dom"; class App extends Component { render(){ return <div>Hello, {this.props.name}!</div> } } ReactDOM.render(<App name="Nathan" />, document.getElementById("root"));
This is the very basis of props: it allows you to send any data you can think of into a component when you call on that component. When you have two components or more, you can pass data around. Here's another example with two components:
As the code above demonstrates, you can pass props between components by adding them when the component is being called, just like you pass arguments when calling on a regular JavaScriptfunction
. And speaking of functions, since React allows you to create a component usingfunction
as well, let's see how props work in a function component next.
Props in a function component
In a function component, components receive props exactly like an ordinary function argument. A function component will receive theprops
object with properties you described in the component call:
import React from "react"; import ReactDOM from "react-dom"; function App() { return <Greeting name="Nathan" age={27} occupation="Software Developer" />; } function Greeting(props) { return ( <p> Hello! I'm {props.name}, a {props.age} years old {props.occupation}. Pleased to meet you! </p> ); } ReactDOM.render(<App />, document.getElementById("root"));
Aside from passing multiple props at once, in this example, you also see theage
prop is a number data type. This demonstrates that you can pass any type of data available in JavaScript — such asnumber
,Boolean
, orobject
— into props. This is how props enable you to send data using the top-down approach, wherein a component at a higher level can send data to a component below it.
Code reuse with props and state
The use of props allows you to reuse more React code and avoid repeating yourself. In the case of our example, you can reuse the sameGreeting
component for many different people:
import React from "react"; import ReactDOM from "react-dom"; function App() { return ( <div> <Greeting name="Nathan" age={27} occupation="Software Developer" /> <Greeting name="Jane" age={24} occupation="Frontend Developer" /> </div> ); } function Greeting(props) { return ( <p> Hello! I'm {props.name}, a {props.age} years old {props.occupation}. Pleased to meet you! </p> ); } ReactDOM.render(<App />, document.getElementById("root"));
That's great! But since props are read-only and must not be changed manually throughout the lifespan of a React application, using only props in your React app doesn't really make it a dynamic app that can respond to user interactions and render accordingly. In order to do that, you need to usestate
.
States and props together form the data "model" of a React application. While props are meant to be read-only, states are used for data that can change based on user actions. Let's see how they work together to create a dynamic application.
First, let's add a new state namedtextSwitch
that stores a Boolean value to theApp
component and pass it to theGreeting
component. TheGreeting
component will look to this state value to decide what to render:
This code example shows how you can conditionally render the view of your application based on user actions withstate
andprops
. In React, states are passed from one component into another component as props. Since prop names and values will just be passed into a component as regularprops
object properties, it's not concerned with where the data is coming from.
propTypes and defaultProps
As you develop your React application, sometimes you might need a prop to be structured and defined to avoid bugs and errors. In the same way afunction
might require mandatory arguments, a React component might require a prop to be defined if it is to be rendered properly.
You can make a mistake and forget to pass a required prop into the component that needs it:
import React from "react"; import ReactDOM from "react-dom"; function App() { return <Greeting name="Nathan" />; } function Greeting(props) { return ( <p> Hello! I'm {props.name}, a {props.age} years old {props.occupation}. Pleased to meet you! </p> ); } ReactDOM.render(<App />, document.getElementById("root"));
Whileprops.age
andprops.occupation
are undefined in theGreeting
component, React will simply ignore the expression to call on their value and render the rest of the text. It doesn't trigger any error, but you know you can't let this kind of thing go unaddressed.
This is wherepropTypes
comes to help.PropTypes
is a special component property that can be used to validate the props you have in a component. It's a separate, optional npm package, so you need to install it first before using it:
npm install --save prop-types
Now let's make required props in theGreeting
component:
import React from "react"; import ReactDOM from "react-dom"; import PropTypes from "prop-types"; function App() { return <Greeting name="Nathan" />; } function Greeting(props) { return ( <p> Hello! I'm {props.name}, a {props.age} years old {props.occupation}. Pleased to meet you! </p> ); } Greeting.propTypes = { name: PropTypes.string.isRequired, // must be a string and defined age: PropTypes.number.isRequired, // must be a number and defined occupation: PropTypes.string.isRequired // must be a string and defined }; ReactDOM.render(<App />, document.getElementById("root"));
With thepropTypes
property declared, theGreeting
component will throw a warning to the console when its props aren't passingpropTypes
validation.
You can also define default values for props in cases where props are not being passed into the component on call by using another special property calleddefaultProps
:
And now the default values indefaultProps
will be used whenGreeting
is called without props.
Learn more about default props in React here.
Passing data from child components to parent components
A parent component is any component that calls other components in its code block, while a child component is simply a component that gets called by a parent component. A parent component passes data down to child components using props.
You might wonder, "How can you pass data up from a child component to a parent component?"
The answer is it's not possible — at least not directly. But here's the thing in React: you can also pass afunction
as props. How is that relevant to the question? Let's first return to the code example withstate
:
import React, { useState } from "react"; import ReactDOM from "react-dom"; function App() { const [textSwitch, setTextSwitch] = useState(true); return ( <div> <button onClick={() => setTextSwitch(!textSwitch)} type="button"> Toggle Name </button> <Greeting text={textSwitch} /> </div> ); } function Greeting(props) { console.log(props.text); if (props.text) { return ( <p> Hello! I'm Nathan and I'm a Software Developer. Pleased to meet you! </p> ); } return ( <p>Hello! I'm Jane and I'm a Frontend Developer. Pleased to meet you!</p> ); } ReactDOM.render(<App />, document.getElementById("root"));
It's very common for a React application to have as many as three component layers, with the top-layer component calling on a child component that calls on another child component. We need to adjust the example above a bit to illustrate this point.
Let's move the<button>
element out ofApp
and into its own component. To make it simple, let's call itChangeGreeting
. You will then call on this component from theGreeting
component instead of theApp
component:
import React, { useState } from "react"; import ReactDOM from "react-dom"; function App() { const [textSwitch, setTextSwitch] = useState(true); return ( <div> <Greeting text={textSwitch} /> </div> ); } function Greeting(props) { let element; if (props.text) { element = ( <p> Hello! I'm Nathan and I'm a Software Developer. Pleased to meet you! </p> ); } else { element = ( <p>Hello! I'm Jane and I'm a Frontend Developer. Pleased to meet you!</p> ); } return ( <div> {element} <ChangeGreeting /> </div> ); } function ChangeGreeting(props) { return ( <button type="button"> Toggle Name </button> ); } ReactDOM.render(<App />, document.getElementById("root"));
Now the button for setting the state is in theChangeGreeting
component, which is two layers down from where the state is (at theApp
component). So how can you possibly change the state? The answer is that you send a function down until it reaches the component that needs it:
In the example above, theApp
component is sending thehandleClick
prop, which has the function to change the state into theGreeting
component. TheGreeting
component didn't actually need it, but its child component,ChangeGreeting
, does, so it forwards the prop there.
On theChangeGreeting
component, it will call on thehandleClick
function when the button is clicked, causingApp
to execute the function.
When the state inApp
is updated, React view is re-rendered, and the new state value is then sent toGreeting
through props.
So, yes — React can't send data up from a child component into its parent component, but the parent component can send a function to a child component. Knowing this, you can send a function that updates state into the child component, and once that function is called, the parent component will update the state.
You can't send data, but you can send a signal for change using a function.
Prop drilling and how to deal with it
The last example for passing data actually represents another common problem you might encounter when dealing with props and state: prop drilling.
Prop drilling refers to passing props down the component layers until they reach the designated child component, while other higher components don't actually need them.
It might seem OK in the example above, but keep in mind that we only have three components there. When you have many components, and all of them are interacting with each other using props and state, prop drilling can become a headache to maintain.
In order to avoid this problem, one of the things you can do is keep the number of components down and only create new components when that particular piece of component needs to be reused.
Back to the example, there is absolutely no need for a separateChangeGreeting
component until another component besidesGreeting
actually calls on the same piece of code. You can do this with only two components:
import React, { useState } from "react"; import ReactDOM from "react-dom"; function App() { const [textSwitch, setTextSwitch] = useState(true); return ( <div> <Greeting text={textSwitch} handleClick={() => setTextSwitch(!textSwitch)} /> </div> ); } function Greeting(props) { let element; if (props.text) { element = ( <p> Hello! I'm Nathan and I'm a Software Developer. Pleased to meet you! </p> ); } else { element = ( <p>Hello! I'm Jane and I'm a Frontend Developer. Pleased to meet you!</p> ); } return ( <div> {element} <button onClick={props.handleClick} type="button"> Toggle Name </button> </div> ); } ReactDOM.render(<App />, document.getElementById("root"));
There you go — no prop drilling necessary for passing down the props this way.
Passing props in React: conclusion
As with all things about learning React, props are easy to learn but hard to master. Now you know that props are immutable (read-only) data used to make React components "talk" to each other. They are very similar to arguments passed to a function, which can be anything specified by developers themselves.
States and props enable you to create a dynamic React application with a solid codebase that is reusable, maintainable, and data-driven.
Full visibility into production React apps
Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you're interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.
LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.
The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.
Modernize how you debug your React apps — start monitoring for free.
Pass Props Back Up to Parent React Native
Source: https://blog.logrocket.com/the-beginners-guide-to-mastering-react-props-3f6f01fd7099/
0 Response to "Pass Props Back Up to Parent React Native"
Post a Comment