Let's Connect the Garden! - Coding with useContext
Making Data Flow Naturally in Your Component Garden

In our previous blog, we explored useContext and how it allows water (data) to flow seamlessly through the entire tree without losing its essence.
However, when I first examined code snippets like these, I often struggled to connect the dots and truly grasp the flow. So, in this article, let’s go a step further — from concept to code — and break down how it all works in practice.
Since useContext is all about accessing data, we’ll begin by setting up some example data. And because our analogy revolves around a tree, our dataset will be… a tree itself! At the top level, we’ll have a branch as the first key. Its value will be an object containing an id and a leaf. The leaf itself will hold another object, which finally expands into a flower:

Now that we have our tree structure, the next step is to set up some React components and files that we’ll use throughout the example. To keep things organized, we’ll create two folders: components and context. Alongside these, we’ll also have our main files — App.js and index.js — to tie everything together.

First, let’s establish the context. This would be our store, where all the variables of functions would be declared, and would be accessible from!
1. Importing the essentials
First, we’ll bring in the React libraries we need —
createContext,useContext, anduseState:import React, { createContext, useContext, useState } from "react";Declaring the context and initial tree
Next, we declare our context and an initial tree structure (from the data model we defined earlier):
const TreeContext = createContext(); const initialTree = { branch: { id: 1, leaf: { flower: "🌸" } } };3. Creating the TreeProvider
Now comes the core piece: the TreeProvider.
Its role is to ensure that our data (the tree) is accessible throughout the React component hierarchy. In other words, it’s the “water source” that supplies data everywhere. Inside ourTreeProvider, we use theuseStatehook to manage the tree’s data. This allows us to not only store the initial tree but also update it dynamically whenever needed. By wrapping our children withTreeContext.Providerand passing thetree(along with any helper functions likeaddBranch) into itsvalue, we make the data available to every component within this provider’s scope. In short, the provider acts as the central source, ensuring that all child components can seamlessly access and interact with the tree without the hassle of prop drilling.export const TreeProvider = ({ children }) => { const [tree, setTree] = useState(initialTree); // Example function to add a branch (we’ll define this further later) const addBranch = (newBranch) => { setTree({ ...tree, ...newBranch }); }; return ( <TreeContext.Provider value={{ tree, addBranch }}> {children} </TreeContext.Provider> ); };4. Making the context reusable
To simplify context usage, we’ll create a custom hook that lets any component access our tree directly:
export const useTree = () => useContext(TreeContext);With this setup, our tree context is now ready to be shared across the app.
For starters, we set up an App.js, from where the Provider will wrap our first component, <Tree/>
import React from "react";
import { TreeProvider } from "./context/TreeContext";
import Branch from "./components/Branch";
const App = () => {
return (
<TreeProvider>
<Branch />
</TreeProvider>
);
};
export default App;
Further, we go deeper in our tree and use our recently created context inside the <Branch/> component.
import React from "react";
import { useTree } from "../context/TreeContext";
import Leaf from "./Leaf";
const Branch = () => {
const { tree, addBranch } = useTree();
const branches = tree.branches;
return (
<div>
<h2>Branches</h2>
<button onClick={addBranch}>➕ Add Branch</button>
{Object.entries(branches).map(([key, branch]) => (
<div key={key}>
<h3>{key} (id: {branch.id})</h3>
<Leaf leaf={branch.leaf} />
</div>
))}
</div>
);
};
export default Branch;
This is a simple execution of our Branch Component — let’s break down what’s happening here:
Importing the context
import { useTree } from "../context/TreeContext";We bring in our custom hook,
useTree, which gives us direct access to the context we created earlier.Extracting values from context
const { tree, addBranch } = useTree();Here, we deconstruct the context to get both the
treedata and theaddBranchfunction.Adding a new branch
<button onClick={addBranch}>➕ Add Branch</button>This button will trigger the
addBranchfunction whenever clicked, allowing us to dynamically grow our tree (we’ll explore this in detail later).Using the tree data
Finally, we can access the
treeobject to pull out its branches, leaves, and IDs for rendering inside our component.
Finally, the Leaf and Flower components are nested inside the Branch components.
import React from "react";
import Flower from "./Flower";
const Leaf = ({ leaf }) => {
return (
<div>
<h3>Leaf</h3>
<Flower flower={leaf.flower} />
</div>
);
};
export default Leaf;
import React from "react";
const Flower = ({ flower }) => {
return (
<div}>
<h4> Flower: {flower}</h4>
</div>
);
};
export default Flower;
You might be wondering — why did we use props for passing down the leaf and flower instead of putting them into the context? To answer this, let’s return to our tree analogy.
Water is essential for every part of the tree, so it flows uniformly throughout — just like our context data. But what about byproducts of the soil that are only useful to a specific part, say the stem? We wouldn’t sprinkle those byproducts everywhere because not all parts need them, and even if we tried, extracting them would be unnecessarily complicated.
Similarly, in React, not all data belongs in context. Some values (like a specific leaf or flower) are only relevant to the immediate child component. In such cases, it’s simpler and cleaner to pass them as props rather than pushing everything through context.
That’s all for today! We’ve taken our first big steps into coding with useContext and building our tree. Next time, we’ll add a fun little function to actually make our tree grow. Until then — keep your roots strong and your branches reaching out!!




