Early days of React part 1


From Raw Notes to React Insights: My Learning Log
Hey everyone! Like many developers, I often jot down quick notes while learning something new. Recently, I've been diving deeper into React (thx to Chai Cohort 1.0), from its early days to its latest advancements. I thought it might be helpful to transform my raw, sometimes chaotic, notes into a more structured blog post. So, let's walk through these concepts together!
Chapter 1: The "Why" and "What" of React
Why React? The “Why” Before the “What”
In the early days of web development, managing complex user interfaces with vanilla JavaScript and jQuery became cumbersome. As applications grew, keeping track of state changes and updating the DOM efficiently was a significant challenge. React emerged to solve these problems by providing a way to build UIs declaratively using reusable components and efficiently managing state updates.
Key painpoints React addressed:
Complex UIs become hard to reason about when you manipulate the DOM directly.
Traditional templating lacks modularity and reusability.
Manual DOM updates lead to performance bottlenecks.
Is React a Library or a Framework?
This is a classic question! So before diving lets distinguish libraries from framework
A library is a collection of functions or tools that you can call upon to perform specific tasks. You are in control of the application flow and decide when and where to use the library's features.
A framework provides a more opinionated structure for your application. It often dictates the architecture and calls your code, rather than you calling its code (Inversion of Control).
React itself is a library. It focuses on the view layer – building user interfaces. However, when you combine React with other libraries like React DOM (for web), React Router (for navigation), and build tools (like those provided by create-react-app or Vite via react-scripts or similar), it starts to feel like a framework. So maybe you can call it a mixture of both, a way of thinking, now you're building within an ecosystem.
A "standalone" React core library (react) wouldn't do much for a web page on its own. It needs react-dom to interact with the browser's DOM.
How React Worked (Pre-React 18 and JSX)
Initially, and up until React 18 made significant strides in server-side rendering, React was primarily browser-based. We write code using JSX (JavaScript XML), which looks like HTML embedded in JavaScript. This JSX isn't understood by browsers directly. A build step (often using a tool like Babel) transpiles (converts) JSX into regular JavaScript function calls (like React.createElement(...)). This JavaScript then manipulates the DOM to render the UI in the browser.
Client-Side vs. Server-Side Rendering (React 19 and Beyond)
Client-Side Rendering (CSR): The traditional React approach. The browser downloads a minimal HTML file and a larger JavaScript bundle. React then runs in the browser to render the page and make it interactive.
Pros: Rich interactivity, streamlined user experience after initial load.
Cons: Can have a larger initial bundle size, potentially slower initial page load (Time to Interactive), and can be less SEO-friendly out-of-the-box.
Server-Side Rendering (SSR): With SSR, the server generates the initial HTML for the page and sends it to the browser. The browser can display this HTML quickly. Then, client-side JavaScript (React) "hydrates" the static HTML, making it interactive.
Pros: Faster perceived initial load (First Contentful Paint), better for SEO.
Cons: Can increase server load, more complex setup initially.
React 19 continues to enhance SSR capabilities and introduces concepts like Server Components, which allow parts of your UI to be rendered on the server and streamed to the client, potentially reducing client-side bundle sizes and improving performance.
Chapter 2: React, ReactDOM, and Rendering in React 19
React & ReactDOM: What's the Deal?
React: The core library responsible for creating components and managing their state and logic. It defines what to render.
ReactDOM: The "glue" between React and the browser's DOM. It provides methods to render React components into the actual web page. react-dom/client is specifically for client-side rendering. In simplified words ReactDOM handles mounting and updating the UI
React 19 Rendering: Client vs. Server Context
React 19 introduced a dedicated pakages (client/server) with subtle diffrence in behavious, i.e. certain event handlers behave differently between client and server. For eg it will give diffrent for onClickapi while it give true on client side and server side false".
This hints at the distinction between what can run on the client versus the server, especially with React Server Components (RSCs).
Client Components: These are the traditional React components we're used to. They can use state, effects, and browser-only APIs (like event handlers such as onClick). They are interactive. You mark a component as a client component with the "use client"; directive at the top of the file.
Server Components: These run on the server. They cannot use state (useState) or lifecycle effects (useEffect) directly, nor can they have event handlers like onClick. Their purpose is to fetch data and render UI on the server. If you need interactivity within a Server Component's output, you'd typically import and render a Client Component within it.
So, an API or prop related to onClick would be relevant and "true" (or functional) in a client-side context, but "false" (or non-applicable/non-functional) in a purely server-side rendering context of a Server Component before it's hydrated or if it's not meant to be interactive.
React 19 aims to streamline how we build applications that can leverage both frontend and server-side rendering effectively.
Here's a basic example using React.createElement (what JSX compiles to) and ReactDOM to render to the DOM:
Chapter 3: Core React Concepts - Components, Props, Virtual DOM, Hydration
Hydration Error
When using SSR, the server sends HTML to the client. Then, React on the client-side takes over. Hydration is the process where client-side React attaches event listeners and makes the server-rendered HTML interactive, essentially "bringing it to life."
A hydration error occurs when the HTML rendered by React on the client during the initial mount does not match the HTML that was sent from the server. This can happen due to various reasons, like using Math.random() directly in render, or differences in timestamps, or conditional rendering based on window object which doesn't exist on server, or mismatched props or component state.
Components & Props
React applications are built using components. Think of them as reusable, self-contained pieces of UI.
The code snippet const Shiv = (props) => { ... } defines a functional component named Shiv.
Props (short for properties) are how components receive data from their parent components. In the Shiv component, props.name and props.cost are used to display dynamic data. Props are read-only within the component that receives them.
Other core concepts include:
Render: The process of describing what the UI should look like. In React, the render method (for class components) or the return value (for functional components) defines this.
Virtual DOM: React uses a Virtual DOM, which is a lightweight JavaScript representation of the actual DOM. When a component's state changes, React creates a new Virtual DOM tree, compares it with the previous one (this process is called "diffing"), and then efficiently updates only the necessary parts of the real DOM. This minimizes direct DOM manipulation, which can be slow.
Chapter 4: Code Formatting with Prettier
Why Prettier?
Manually formatting code to be consistent across a team (or even for your own sanity) is tedious. Prettier is an opinionated code formatter.
Why we need it: It enforces a consistent code style, reduces debates over formatting, and makes code reviews easier by focusing on logic rather than style.
Basic commands:
npx prettier --write .: Formats all supported files in the current directory and subdirectories.
npx prettier --check .: Checks if files are formatted, without changing them (useful for CI). You can add a script to your package.json:
Then you can run npm run format.
.prettierignore
Just like .gitignore, you can create a .prettierignore file to tell Prettier which files or directories it should skip.
Chapter 5: Code Linting with ESLint
What is ESLint and How to Use It?
While Prettier handles formatting, ESLint is a tool for linting. Linting means analyzing code for potential errors, bugs, stylistic issues (that go beyond just formatting), and suspicious constructs.
It helps catch errors early.
It enforces coding standards and best practices.
To install it: npm install --save-dev eslint
You'll then typically configure ESLint with a configuration file (e.g., .eslintrc.js) and often use plugins for specific frameworks like React (e.g., eslint-plugin-react).
Difference Between Prettier and Linting (ESLint)
Prettier: Focuses only on code formatting (indentation, line breaks, spacing, etc.). It's opinionated and has few configuration options.
ESLint: Focuses on code quality and finding errors. It can also enforce some style rules, but it's more about correctness and best practices. It's highly configurable.
Many developers use both: ESLint for code quality and Prettier (often via an ESLint plugin like eslint-plugin-prettier and eslint-config-prettier) to handle formatting, letting each tool do what it does best.
Chapter 6: JSX - HTML-like Syntax in JavaScript
How Can JavaScript Have HTML Features?
It doesn't, directly. That's where JSX comes in.
Writing UI structures with React.createElement can be very verbose and hard to read, as seen in earlier examples:
This is "hard and boring," and traditional HTML feels "much more easy."
JSX to the Rescue!
To make UI creation more intuitive, React introduced JSX. It allows you to write HTML-like syntax directly within your JavaScript code.
note before JSX, we can do something very close to that with help of Babel
Babel is a JavaScript compiler that transpiles modern JavaScript (including JSX) into older JavaScript that browsers can understand. So, when you write JSX, Babel converts it into React.createElement(...) calls behind the scenes. JSX is essentially syntactic sugar.
Chapter 7: Handling Web Requests (API Calls)
Fetching data from a server is a common task in web applications.
Two common scenarios for handling CORS issues:
Development: Using a Proxy
Problem: When your frontend (e.g., running on http://localhost:5173) tries to make an API request to a backend server (e.g., http://localhost:3000/api/data), the browser's Same-Origin Policy might block the request due to CORS (Cross-Origin Resource Sharing) issues.
Solution (Development): Many development servers (like Vite's or create-react-app's) allow to configure a proxy.
For eg, we might configure our dev server so that any request to /api on my frontend's port (e.g., http://localhost:5173/api/users) is automatically forwarded to my backend server (e.g., http://localhost:3000/api/users).
The changeOrigin: true option is important for some backend configurations.
How it works: The browser makes a request to dev server (same origin). The dev server then makes the request to the actual backend API. Since server-to-server requests aren't subject to browser CORS policies, this works around the issue during development.
Production: Backend CORS Configuration
Problem: Proxies are a development-only solution. In production, frontend is served from one domain, and API might be on another.
Solution (Production): The backend server must be configured to include the correct CORS headers (like Access-Control-Allow-Origin, Access-Control-Allow-Methods, etc.) in its responses. This tells the browser that it's safe for frontend's origin to access the API.
In Next Section we'll talk about Hooks and Life Cycle of React Components and more
Subscribe to my newsletter
Read articles from Shivprasad Roul directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Shivprasad Roul
Shivprasad Roul
Software developer with a strong foundation in React, Node.js, PostgreSQL, and AI-driven applications. Experienced in remote sensing, satellite image analysis, and vector databases. Passionate about defense tech, space applications, and problem-solving. Currently building AI-powered solutions and preparing for a future in special forces.