Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Browse all series

React from Scratch

React from Scratch is a hands-on, beginner-friendly video series that takes you from an empty folder to a fully interactive React app — no prior React knowledge required. You'll learn about JSX, components, state management, controlled inputs, data fetching, and even TypeScript!

I hope you'll come to appreciate React for what it truly is: a flexible, powerful UI library — not a full-blown framework. I'll teach you where its boundaries lie, and how to scale beyond them.

Progress

Series Info

Episodes
27
Run Time
4h 10m
Difficulty
Beginner
Last Updated
Apr 7, 2025
Version
Latest

Series Episodes

  1. Introduction (1)
    1. Why React?

      Before we begin our learning journey, let's take a look at a few good reasons why learning React is indeed a great idea.
  2. Fundamentals (7)
    1. Starting From Absolute Scratch

      We start from the absolute beginning, with an empty new folder. We setup a quick dev server with Vite.
    2. React "Hello World" Preview

      We look at what it takes to output a React "Hello World" in the browser. We learn that a "build step" is needed to convert JSX to something the browser can understand. For this lesson, we take a shortcut and use Babel to convert our JSX directly in the browser.
    3. JSX - Give it 5 Minutes

      Let's take a minute (or 5) to process what JSX really is. It helps to look at what JSX actually compiles to: a series of nested React.createElement() function calls. Looking at JSX and its output side by side, it doesn't take long to appreciate the clarity and familiarity of the JSX syntax!
    4. JSX Gotchas for Newcomers

      There are many rakes that newcomers to React and JSX can step on. We go through a few "classic" gotchas of JSX, hopefully keeping your forehead rake-stick-mark free!
    5. Proper Build Step With Vite

      Let's progress from a shortcut solution to a proper build step. We add the Vite React plugin so that our dev server knows how to handle JSX files.
    6. Styling Techniques in React

      We look at various approaches to styling React applications, from good old "normal" CSS to CSS-in-JavaScript solutions. Eventually, we settle on using... surprise surprise... Tailwind CSS! We set up Tailwind CSS v4 from scratch, and we're ready to finally start building something!
    7. Quick Housekeeping

      I know I keep saying we're going to build stuff. I PROMISE we will start in the next video. Just a few housekeeping duties I took care of "offline" and I need to tell you about. These will save us some headaches down the road!
  3. Components & Templating (5)
    1. Breaking Down Components

      Let me introduce you to the Dev Pups app! For now, it's just a static HTML template. Nothing works — it's just a pretty UI built with HTML and CSS. We'll start converting the header section into a React component (or partial), and further break it into smaller components to make the giant markup chunk more manageable.
    2. Completing the Static UI Migration

      We take the rest of the static HTML markup, run it through Transform.tools to convert it to JSX, and bring it within our React app. We break down the new markup into three components: Shortlist, PuppiesList and NewPuppyForm.
    3. Iterating Through Data

      The repetitive list items in the PuppiesList are pretty alarming! This is not DRY! Do we need another component? Hmmm, maybe — but we can also have some sort of "loop" to iterate over data. We need the equivalent of @foreach in Blade, or v-for in Vue. How do we do that with JSX?
    4. Passing Data to Components

      More than just the PuppiesList component will need to access the puppies data, so we need to move it to a place where we can share it around. We look at how to "pass down" data through components in React, using props.
    5. TypeScript is Your Friend. Really!

      I know, I know. Ugh. TypeScript. I used to get angry at it too. What I'm hoping is this lesson can change your mind, or at least show you that TypeScript can be super useful without being super annoying. You don't have to use TypeScript, but my recommendation is to get used to it, as it's ubiquitous in the React ecosystem.
  4. State & Reactivity (5)
    1. A First Taste of Interactivity

      This is the big one! That's probably what you've been waiting for, too. We dive into React's "state", and its component re-rendering cycle. This is a pivotal lesson in your React learning journey, so watch it multiple times if you need to.
    2. Sharing State Across Components

      JSX is highly composable and flexible. To become great at React, you must embrace an iterative refactoring mindset, change and move things around as new requirements come up. We'll convert our "isLiked" boolean to an array of puppy IDs. We'll also "lift" the state higher up the render tree, so it can be shared with other components like the Shortlist. We'll pass that state down multiple levels deep. Your first feel of what's called "prop drilling".
    3. State, Props and Re-render Cycles

      After going over the implementation of the Shortlist component to work with the liked puppies state, we take a deeper dive in React's props, state and re-render cycles. We add a neat little browser tool called React Scan, which gives us insights on when components re-render, and whether or not those re-renders affect the performance of the application. A great addition to your React developer toolbelt!
    4. Prop Drilling and the Context API

      I want you to know about the Context API in React. I don't necessarily think we should use it inside our small Dev Pups app, but it's important you know about it and when to reach for it. We'll look at how to set up a context provider, and how it opens a magic back door to skip the drilling of props down multiple components. With the use() function, we can access the context value from anywhere we need, as long as it's within the context provider wrapper. We'll even build a custom React hook that enhances the developer experience with a more meaningful error message in cases where someone tries to access context value in a wrong way!
    5. Controlled Vs Uncontrolled Inputs

      Let's implement the search/filtering functionality. We'll once again use some shared state for it. But this time, we're using an HTML input field. We'll take over the control of its value, effectively turning it into a "controlled input" in React lingo. You can sort of think about it as "two-way data binding" in frameworks like Vue or Angular.
  5. Forms (2)
    1. Form Actions

      We've looked at controlled inputs. This time, we're going to let the browser do its thing by using uncontrolled inputs, and rely on the form submit event to handle updates. We'll first do it the "manual" way, and then look at React Form Actions, which take care of a handful of useful things for us.
    2. Pending State

      Introducing an artificial (or real!) delay in actions instantly makes an app feel unresponsive or flat out broken. We look at a few approaches to mitigate this and provide a "pending UI" to our users to show them something is happening. We take a look at the useFormStatus hook which gives us access to useful properties related to a form submission.
  6. Data Fetching & Remote State (6)
    1. Data Fetching With useEffect

      From this lesson forward, we are entering the "React is just a UI rendering library" territory. We'll look at concepts that can be done inside React, but for which there are no set recommendations or patterns. It's still important to understand how to go about it, but as you watch the next few lessons, keep in mind that you'll likely reach for a tool or "meta framework" for most of the things we'll be looking at.
    2. Suspense, Error Boundaries, and the use() Function

      While the recommendation is still to use a library or meta framework for handling external data, let's take a look at how React's use() function and <Suspense/> component make handling data fetching a little nicer to work with.
    3. TypeScript-Driven Refactoring

      TypeScript is somewhat useful while developing, but its true value really shines when it's time to do some refactoring. We'll try to flow the new API puppies data through our React app, and turn to TypeScript for guidance on where things need refactoring. I really think that if you were skeptical about TypeScript, this video might change your mind. And if not, that's still fine, we can still be friends!
    4. Remote Data Mutations

      By fetching the API data and setting it to local state in our app, we've essentially created "derived state". This is great until the actual data on the database changes. Introducing data mutations in our app painfully exposes this problem: we are able to update the data via the API, but the changes are not reflected in the UI. Our puppies data in our app is now stale! Turns out keeping remote state in sync is quite a tricky problem - and once again something that some libraries specialize in. Here, let's "hack" the API to return the new puppies data in the mutation response so we can update our state accordingly.
    5. Revisiting the toggle Implementation

      I couldn't sleep properly after modifying the API response just to facilitate our job on the front end. Let's revert that, and do the extra bit of work to re-derive the API puppies data after performing a like toggle mutation. That's really not a whole lot of work, and I'll get better sleep going forward — good tradeoff!
    6. Persisting New Puppies via the API

      Let's update our NewPuppyForm to hit the API with a POST request. We'll discuss some rudimentary error handling and validation error messages.
  7. Where to Go From Here? (1)
    1. React is a Library, Not a Framework

      I've said it over and over since lesson 21: "For this, you'd probably use a library". Let's back up that statement by looking at the React docs, and discuss the landscape of said React libraries and meta frameworks. We take a quick look at a version of the Dev Pups app built with Laravel, Inertia and React — quite possibly the best way to solve all our data fetching and async state problems, if you're a Laravel developer!

Continue Learning