Introduction
Dynamic variables are exclusive to their components. know nothing about dynamic variables? You got to be kidding! Check out my most recent piece on the UseState hook.
In a React application, sometimes you may want a variable to be accessible by more than one component. Using "props drilling" or the "Context API" is one way to pass dynamic variables from one component to another.
Since the code base is shifting away from class-based components and toward functional programming, our discussion in this article will be limited to functional components.
What are Functional Components?
According to the MDN Documentation, Functions are one of the fundamental building blocks in JavaScript. Think of it as a procedure or a set of statements that performs a specific task.
If you were planning to build a house, you wouldn't simply begin with the roof. You must have a blueprint. If my assumption is true, you'll want to divide the task into simpler stages by getting the foundations laid first, building and completing any necessary roofing, plumbing, or electrical work. This idea also has a connection to functions. Dividing a complex problem into manageable steps to address a specific issue.
React functional components are nothing more or less than simple JavaScript functions. It produces a JSX template that resembles HTML and contains its logic.
Similar to how functions are reused in JavaScript, React components are reusable if exported. Let's develop a reusable button component to test this concept.
// Creating a reusable button component
export function Button() {
return (
<button>Click me</button>
);
}
// Home component
function Home() {
return (
<section>
<Button />
</section>
);
}
export default Home;
From the example above, note that;
- All React components must begin with a capital letter
Rather than having to manually hardcode a button tag each time you required one, you can just import the Button component and reuse its template.
What are Props?
Don't Repeat Yourself, or "DRY," is a notion used in functional programming. You must avoid redeclaring the same values or tags in several components. To do this, you can utilize the concept of props.
In Shivangi Rajde article on Props in React, she stated that 'Props are special objects used to transport data from one component to another.'
Using the concept of props, let’s provide the button component access to a dynamic variable called text. Let’s have a look?
//Reusable Button Component
export function Button (props) {
return (
<button>{props.text}</button>
)
}
//Parent Component
function Home() {
return (
<div>
<h1>Concept of Props</h1>
<Button text = 'Click me'/>
</div>
);
}
export default Home;
In the previous example, I'm simply passing a dynamic variable to the button component as a prop. The props object in the Button component can be used to access the variable text.
In your React web application, there are undoubtedly going to be a lot of buttons. In order to write less code, you'll need to employ the idea of props to make those components dynamic and reusable.
To be sure that you thoroughly grasp this idea, let's look at one more example.
//Reusable Button Component
//de-structuring props
export function Button ({text, url}) {
return (
<a href={url}> <button>{text}</button></a>
)
}
//Parent Component
function App() {
return (
<div>
<h1>Concept of Props</h1>
<Button text = 'Click me' url ='google.com'/>
</div>
);
}
export default Home;
A component's data can also be retrieved by destructuring the props object which is way cleaner. This way, the object props value only has to be passed inside the component parameter. This example serves as a good reminder that we can pass numerous properties to a single component. Also note that Props are passed from parent to child and never vice versa.
Great, it seems you now have a fundamental grasp of how props operate. I'm sure you're wondering what the Context API accomplishes, given that Props do indeed give us dynamic ability and reusability. I'll walk you through props drilling, and before long, the Context API will rank among your favourite hooks.
What is Props Drilling?
Props Drilling is the process of moving data from one component to another. Assume you have a React web application with several Components, and we need to pass data to these nested components. Isn't this already getting tedious? Yes! But let's start with an illustration to see how it functions. We have been working with a single file for quite some time, but this time we will likely work with several components separated into different files.
For this example, I'll generate a few dynamic variables in the parent component [App.js] and then send these values to the home component and its sub components. This will help you understand how the Props drilling method works. Let's take a look;
//Parent Component
import Home from "./Home";
// declaring dynamic variables
const text = "sign up";
const url = "google.com";
function App() {
return (
<main className="App">
<Home text={text} url={url} />
</main>
);
}
export default App;
//Home Component
import Form from "./Form";
//de-structuring props
function Home({ text, url }) {
return (
<main className="Home">
<h2>Welcome to the Home page</h2>
<Form text={text} url={url} />
</main>
);
}
export default Home;
//Nested component
//de-structuring props
function Form({ url, text }) {
return (
<div className="Home">
<h5>Welcome to the Form page</h5>
<a href={url}>
<button>{text}</button>
</a>
</div>
);
}
export default Form;
I am aware that you are unsure about the appropriate time to use these concepts, but to allay your concerns, I will provide an example.
If you were creating an e-commerce website and needed the number of products added to the cart to be displayed on every page of the web application, you could use this concept to send the cart value to each page instead of hardcoding the logic every time you needed it.
Doesn't props drilling solve this? Yes it does! However, it is a time-consuming process. You may need to pass data to components that do not require certain data because they have nested components that do, which is why you should learn how to use the Context API.
The Context API
The Context API allows you create global variables that can be passed around. You do not have to manually pass data from one component to another in this context. Simply define your data in the parent component and use the context Provider, and every component and nested component will be able to access the declared data.
How to create globally accessible variables
Import the create context hook.
Initialize the create context hook, store it in a variable and export it.
Wrap the components inside the context provider, and pass the global variables as a value.
Let's try to create a global cart variable that can be passed to different components using the Context API.
//import the create context hook
import { createContext, useState } from "react";
import Home from "./Home";
//assign a variable to the initialized hook and export
export const cartContext = createContext();
function App() {
const [cart, setCart] = useState(0);
//provide the global variable
return (
<cartContext.Provider value={cart}>
<Home />
</cartContext.Provider>
);
}
export default App;
Any component nested in the Parent component, as well as components nested in its children components, can now access the declared variable cart. Let's look at how to get at these variables now.
Steps to access variables that are globally declared
import the useContext hook
import the created context hook
retrieve the global variable by Initializing the useContext hook and passing the context variable.
Utilize the global variable
//import the useContext hook
import { useContext } from "react";
//import the declared context hook
import { cartContext } from "./App";
function Home() {
//retrieve the global variable by Initializing the useContext hook and passing the context variable.
const cart = useContext(cartContext);
return (
<main>
<nav style={{ display: "flex", justifyContent: "space-between" }}>
<ul>
<li>Home</li>
<li>Cart {cart}</li>
</ul>
</nav>
</main>
);
}
export default Home;
In this example, we simply created a global variable rather than drilling each variable to each component as we did previously, and that is all there is to using the Context API hook.
Summary
You may initially find the Context API syntax to be complicated, and I completely understand that feeling. However, I'm also confident that once you figure it out, you'll adore and value its functionality. Give this article a thumbs up if you liked it and let me know what you think of it in the comment section below.