PSchool Logo

PSchool

Home Page

Introduction to ReactJS

Why React? The Component Model
The problem React solves: keeping the UI in sync with data without manually updating the DOM. The component model — breaking a UI into small, reusable, self-contained pieces. React's place in the ecosystem: a UI library, not a full framework. Setting up a React project with Vite (create-vite) and a tour of the project structure.
Start
JSX
JSX as syntactic sugar for React.createElement() — what the compiler transforms it into. JSX rules: single root element (or Fragment), className instead of class, camelCase attributes, and self-closing tags. Embedding JavaScript expressions inside JSX with curly braces. Conditional rendering: ternary expressions, short-circuit &&, and extracted variables.
Start
Components and Props
Function components as plain JavaScript functions that return JSX. Passing data down with props — reading them, providing default values, and the children prop. Prop types for documentation and runtime warnings with PropTypes. Component composition: building complex UIs by nesting simpler components.
Start
Rendering Lists and Conditional UI
Rendering arrays of data with Array.map() inside JSX. The key prop — why React requires it, what makes a good key, and the bugs caused by using index as key. Conditional rendering patterns: hiding components, showing placeholders, and toggling between views. Rendering nothing with null and fragments (<> </>) to avoid extra DOM nodes.
Start
State and useState
Why local variables don't work for UI state — and what makes React's state different. The useState hook: declaring state, reading it, and updating it with the setter function. State is a snapshot: why you should never mutate state directly. Updating objects and arrays in state immutably — the spread pattern and Array methods. Lifting state up to share it between sibling components.
Start
Handling Events and Forms
Attaching event handlers in JSX: onClick, onChange, onSubmit, and other synthetic events. The SyntheticEvent object and calling preventDefault(). Controlled components for forms: binding input value to state and handling changes. Uncontrolled components and useRef for cases where controlled is overkill. Form validation patterns: inline error messages and disabling the submit button.
Start
useEffect and Side Effects
What a side effect is: data fetching, subscriptions, timers, and direct DOM access. The useEffect hook: the effect function, the dependency array, and the cleanup function. The three forms: run after every render, run once on mount, and run when specific values change. Fetching data with useEffect and the Fetch API — handling loading, success, and error states. Avoiding the stale closure problem by listing all dependencies correctly.
Start
useRef and the DOM
useRef for persisting a mutable value across renders without triggering a re-render. Attaching a ref to a DOM element to read its properties or call its methods (focus, scroll, play). The difference between refs and state — when to use each. Forwarding refs to child components with forwardRef.
Start
useContext — Sharing State
The prop-drilling problem and when it becomes painful. Creating a context with createContext, providing it with Provider, and consuming it with useContext. When to use context vs lifting state vs a dedicated state manager. Building a practical theme toggle and a current-user context for an app.
Start
useReducer — Complex State Logic
When useState becomes unwieldy: multiple related state fields and complex update logic. The reducer pattern: state + action → new state. The useReducer hook: dispatch, actions, and the action type convention. Comparing useReducer to useState — choosing the right tool. Combining useReducer with useContext as a lightweight alternative to Redux for medium-sized apps.
Start
Custom Hooks
Extracting repeated logic from components into reusable custom hooks. The rules of hooks — why hooks must be called at the top level and only from React functions. Building useful custom hooks: useFetch, useLocalStorage, useDebounce, and useWindowSize. Publishing and sharing custom hooks — how the community ecosystem (react-use, ahooks) works.
Start
React Router
Client-side routing: how a single-page app changes views without a full page reload. Setting up React Router: BrowserRouter, Routes, Route, Link, and NavLink. Dynamic routes with URL parameters (:id) and reading them with useParams. Programmatic navigation with useNavigate. Nested routes, layouts, and 404 not-found pages.
Start
Performance Optimisation
How React decides what to re-render: the reconciliation algorithm and the virtual DOM. Preventing unnecessary re-renders with React.memo for components and useMemo / useCallback for values and functions. Code splitting and lazy loading routes with React.lazy and Suspense. Profiling a React app with the React DevTools Profiler to find and fix bottlenecks.
Start
Testing React Components
Testing philosophy: testing behaviour, not implementation. Setting up Vitest and React Testing Library. Querying the rendered DOM: getByRole, getByText, getByLabelText, and findBy for async. Firing events with userEvent and asserting on the result. Mocking fetch calls and testing async components.
Start
Building and Deploying a React App
A capstone project: building a full-featured single-page app with routing, context, data fetching, and forms. Production build with Vite: bundle analysis, environment variables, and optimisation. Deployment to Vercel and Netlify — connecting a Git repository for continuous deployment. An introduction to Next.js as the natural next step for server-side rendering and full-stack React.
Start