Every React Concept Explained

Written by Massa Medi
React is a JavaScript library with a reputation for tossing around fancy terms like reconciliation, composition, and error boundaries. But what do all these terms actually mean? If you've felt lost in the jargon, buckle up: we're going to walk through the essentials of React, from its foundational building blocks to advanced architectural features—no prior experience required.
Let's Start at the Beginning: Components
React applications are built with components—the fundamental units that make up everything visible in your app. Think of components like Lego blocks: you can use them to construct simple items like buttons and inputs, or snap several together to build entire pages. You can reuse components as often as you want, giving your projects versatility and consistency.
Each React component is just a JavaScript function that returns markup. But here's the twist: React components don't return plain HTML. Instead, they use something called JSX—JavaScript syntax that looks like HTML but is actually JavaScript in disguise. JSX makes writing UIs much cleaner and easier to read than using React’s createElement
function (which, frankly, gets old very fast).
JSX: JavaScript in a Fake Mustache
JSX, though optional, is nearly universal in React codebases. However, since it's JavaScript, there are some differences from HTML. For example, you must use camelCase for attributes. Instead of writing class
in HTML, React requires className
. That's because class
is a reserved word in JavaScript.
HTML is largely static and unchanging, but React and JSX shine because you can inject dynamic JavaScript values directly into your markup using curly braces ({}
). Inside these curly braces, you can use numbers, strings, variables, and even entire functions. This dynamic power lets you display up-to-date values, style elements conditionally, and pass logic straight into your UI.
Every Component Needs a Parent
Since React components are just functions that return a value, each must return one parent element. If you try to return multiple sibling elements at the root, React will throw a big error. Developers often wrap their components in a <div>
, but if you don’t want to clutter your DOM, you can use a React Fragment—written as <></>
—to group elements without adding extra nodes to the HTML page.
Passing Data: Props and the Magic of Composition
What if you want to pass information into a component? That's where props come in. To define a prop, simply add it as an attribute to your component (<Hello name="Alice" />
). Inside your component, props arrive as an object and can be accessed with standard JavaScript syntax: props.name
.
Props are like custom attributes you can send to any component—and yes, you can pass anything: strings, numbers, objects, arrays, and even other components. This brings us to the children prop. If you use both opening and closing tags for a component, you can nest other React elements inside. Those become accessible as props.children
. This approach fuels Composition, organizing your app’s building blocks in a flexible, powerful way.
The children prop shines for layout components. For instance, you might have a <Card>
component that gives its children a consistent style—handy for rendering multiple unique users, posts, or products in a visually uniform way.
The Misunderstood “Key” Prop
There's another built-in prop in React: key. Despite its name, it doesn't unlock secret features! The key prop helps React keep track of elements in lists, improving performance and stability. When mapping over arrays to generate UI—say, a list of to-do items—each element needs a unique key
. If you forget, React will remind you (with console warnings). If nothing unique exists, use the current index
as a fallback.
Rendering: From Code to Browser
You might be wondering: how does React transform your components into visible content in the browser? This process is called rendering. Under the hood, React uses a clever strategy to make this fast and efficient, leveraging something called the virtual DOM (vdom).
The DOM—short for Document Object Model—is how browsers internally structure all the elements of a web page, typically represented as a tree. React maintains its own virtual DOM in memory. When the state of your app changes, React updates the virtual DOM first, which is much quicker than updating the real DOM. Then, React uses a process calleddiffing to compare the new virtual DOM with the previous version, detecting what changed. Through reconciliation, only those changed parts are updated in the real DOM, giving you speedy, efficient updates.
React Event Handling: Linking Users and Code
Users interact with your app through many different events—clicks, mouse movements, keypresses, and more. Event handling lets you respond to these events. React offers built-in events like onClick
,onChange
, and onSubmit
. For example, you might attach onClick
to a button and trigger a function when that button is clicked, such as displaying an alert or updating a counter.
State: The Lifeblood of React Apps
To keep track of data that changes over time (like a photo gallery's current image, the number of “likes,” or the value in an input box), React uses state. But don't confuse this with a “state” on the map! State in React is like a camera snapshot—it represents the app at a specific moment.
You can't just use regular JavaScript variables for state, since updating those won't trigger a re-render. Instead, React gives us hooks like useState
and useReducer
to manage dynamic values. useState
returns a pair—your state variable and a function to update it. Update the state, and React updates your UI. It's as simple as const [likes, setLikes] = useState(0);
, then increasing likes
each time the user clicks the “like” button.
Controlled Components
Controlled components make use of state to keep form elements in sync. For example, consider a text input: with a controlled component, every keystroke updates state, and the input always reflects that state. Here's what happens:
- User types into the input field.
- The
setValue
function puts the value into state. - The input's
value
prop reads from state, ensuring it always displays the latest text.
This pattern ensures your app's UI is predictable and easy to debug: if you need to change the component’s behavior, simply amend the controlling state.
React Hooks: Your Tools for Managing Everything
Hooks are special functions that provide access to React features inside function components. The five main hook types are:
- State Hooks:
useState
anduseReducer
for managing local component state. - Context Hooks:
useContext
for accessing globally shared values. - Ref Hooks:
useRef
for directly referencing DOM elements or storing mutable values. - Effect Hooks:
useEffect
for interacting with external systems and side effects (like AJAX calls, timers, or subscriptions). - Performance Hooks:
useMemo
anduseCallback
, which optimize performance by caching values or functions to avoid expensive recalculations.
Realistically, you'll use useState
, useEffect
, and useRef
most often in day-to-day projects.
Purity: Keeping React Components Predictable
In programming, “purity” refers to a function always producing the same output given the same input (like a math formula). Pure React components should only render their JSX and never modify variables or objects outside their scope during render. If a component mutates external state while rendering (like incrementing a counter each time it displays), the output can become unreliable, especially when reusing the component.
To help developers write pure components, React provides StrictMode—a wrapper component that highlights risky or unsafe patterns as you develop. Just wrap your app in <StrictMode>
and React will alert you to anti-patterns before they break your application.
Working with External Systems: Effects, Side Effects, and useEffect
Sometimes you need to interact with systems outside of React: for example, fetching data from a server or using browser APIs. This is called handling side effects. While many effects are best handled inside event handlers (like Ping! Sending a server request after someone clicks “submit”), some should run during the component’s lifecycle.useEffect
is React’s hook for running side effects when components mount, update, or unmount—such as fetching initial data or cleaning up event listeners.
Accessing the Real DOM: useRef
and the ref
Prop
Occasionally, you need to work with the actual DOM—directly focusing an input, measuring an element’s size, or integrating with third-party UI libraries. In those cases, useRef
lets you create a reference object, and the ref
attribute attaches it to a React element. Unlike state, updating a ref does not cause a re-render. This approach is often easier and more robust than trying to force React to handle everything indirectly.
Sharing Data Across Components: Context
As React apps grow, you’ll likely have deeply nested components that require access to shared data (think user info, themes, or language settings). Passing props down multiple levels gets unwieldy. Enter Context: a built-in feature that lets you share values throughout your component tree—without manual prop drilling.
To use context, you:
- Create a context object in a parent component.
- Wrap the target subtree in a
Context.Provider
and specify the value to share. - In any nested child, call
useContext
to access the shared value directly, no matter how deep it sits in the tree.
This powerful pattern drastically reduces complexity in large apps.
Portals: Breaking Out of the DOM Hierarchy
Sometimes, you want a React component to appear elsewhere in the HTML structure—outside its parent container. Enter Portals. Portals allow you to render children into any DOM node you choose. This is invaluable for UI elements like modals, dropdown menus, or tooltips, which might otherwise get visually trapped by their parent’s styles.
To create a Portal, use the createPortal
function. Pass in your component and the DOM node where it should appear—a modal dialog, for example, layered over the entire page.
Suspense: Handling Loading States Gracefully
Suspense is a React feature that improves the user experience by showing fallback content (like a spinner or custom message) while a component or its data is loading. Simply wrap the slow-loading component in a <Suspense>
component and provide fallback content. This pattern also makes lazy loading components straightforward, helping apps feel snappy even when working with large bundles or network delays.
Error Boundaries: Keeping Your App Resilient
Even the best apps encounter errors, and in React, rendering errors can bring down your entire UI. Error boundaries are specially designed components that catch rendering errors in their subtree and display fallback UI, preventing a total crash.
For example, suppose a certain component throws an error if a user isn’t defined. By wrapping this section in an Error Boundary, you can display a custom message (such as “Oops, something went wrong!”) instead of a blank screen or error dump.
Ready to Go Deeper?
React is a vast library with endless possibilities. If you’re eager to master these concepts and more, check out the full bootcamp at reactbootcamp.dev. Whether you’re just starting or refining your skills, there’s plenty to learn and explore.
We hope you learned a lot in this guide—see you in the next one!
Recommended Articles
Code Report

From SaaS Panic to Open Source Paradise: The Ultimate Guide to Escaping Subscription Hell

The Best Frameworks for Solo SaaS Builders: Navigating Laravel, Next.js, and Beyond

The Definitive Beginner’s Guide to Picking Your Tech Stack for Web, Mobile, Desktop, Games, and AI

From File Chaos to Geek Zen: How I Built My Own Home Lab, NAS Server, and Music Streaming Empire

What Are Algorithms, Really? The Truth Behind the Technology Shaping Our World

Every Python Library and Frameworks Explained

All The JavaScript You Need To Know For React

How to Learn JavaScript FAST in 2025

ALL React Hooks Explained: When, Why, and How to Use Every Hook in Your React Toolkit
