Skip to main content

React Fundamentals

Components, JSX, State, and Re-rendering

Updated 8 min readMarkdown
React Fundamentals

"Why did developers create React when JavaScript already existed?"

Before React, JavaScript was used for fetching some data, finding some element using document.getElementById() adding or removing CSS classes, updating inner text, and attaching event listeners.

This works well with small applications, but when it comes to large-scale applications that handle user profiles, live feeds, notifications, and forms, it faces problems syncing the UI, as a single state change might require updating five different places in the DOM. If we miss one, the UI gets out of sync.

To fix this issue, Facebook created React in the year of 2013 to solve this UI complexity Instead of manually reaching into the browser's DOM to manipulate elements step-by-step, React allows developers to describe what the UI should look like for any given state, and automatically handles all the updates under the hood.

1. Why React Exists

Problems with Traditional DOM Manipulation

In traditional web development, you use imperative programming. You give the browser step-by-step instructions on how to change the DOM:

// Imperative vanilla JS
const button = document.getElementById('like-btn');
button.addEventListener('click', () => {
  count++;
  const countSpan = document.getElementById('like-count');
  countSpan.innerText = count;
  button.classList.add('liked');
});

As user interfaces grow, managing dependencies between raw DOM elements leads to "spaghetti code." It becomes extremely hard to track which event handler modified which element.

The Component-Driven Approach

React introduced Component-Driven Development. In this Instead of viewing a web page as a single massive document, React treats UI as a collection of independent, reusable pieces called components.

Whether it is a User Profile, a Product Card, a Social Media Post, or a Dashboard Widget, complex interfaces are broken down into smaller, self-contained building blocks.

Components are portable and shareable.

Syntax-

function App (){
//Todo
  return(
    //JSX - TSX
 )
}

What is JSX?

JSX stands for JavaScript XML (JS + HTML). It is a syntax extension for JavaScript that allows you to write HTML-like markup directly inside JavaScript files.

const userCard = (
  <div className="user-card">
    <h2>Siddhartha Mohapatra</h2>
    <p>Software Engineer</p>
  </div>
);

Why JSX Was Introduced

Before React, HTML for structure, CSS for styles, and JS for logic. However, modern interactive UIs tightly couple rendering logic with user interaction logic. JSX allows you to keep component UI and logic together in one place.

JSX vs HTML

While JSX looks like HTML, it is stricter and has a few key differences:

  • className instead of class: Since class is a reserved keyword in JavaScript, React uses className.
  • Self-closing tags: All tags must be explicitly closed (e.g., <img /> or <input />).
  • CamelCase attributes: Attributes like onclick become onClick, and tabindex becomes tabIndex.

Embedding JavaScript inside JSX

You can embed any valid JavaScript expression inside JSX by wrapping it in curly braces {}:

const username = "Siddhartha";
const unreadMessages = 5;

return (
  <div>
    <h1>Welcome back, {username}!</h1>
    <p>You have {unreadMessages * 2} pending notifications.</p>
  </div>
);

High-Level Compilation Process

Browsers do not understand JSX directly. A compiler like Babel transpiles JSX into standard JavaScript function calls React.createElement):

JSX Input:
<h1 className="title">Hello World</h1>

Compiled Output:
React.createElement('h1', { className: 'title' }, 'Hello World');

3. Components in React

What is a Component?

A React component is a JavaScript function that returns JSX. Components act as custom HTML elements with their own visual structure and logic.

// A simple function component
function ProductCard() {
  return (
    <div className="product-card">
      <img src="laptop.jpg" alt="Laptop" />
      <h3>Wireless Headphones</h3>
      <p>$99.99</p>
      <button>Add to Cart</button>
    </div>
  );
}
export default ProductCard

Component Composition

You can combine smaller components to construct larger UIs. For example, a Social Media Feed can be composed of multiple Post components, which in turn contain Avatar, LikeButton, and Comment components.

function SocialFeed() {
  return (
    <div className="feed">
      <Post />
      <Post />
      <Post />
    </div>
  );
}
export default SocialFeed

4. Props in React

What are Props?

Props (short for properties) are inputs passed into React components. They make components dynamic and reusable rather than hardcoded.

Passing and Using Props

Data flows sequentially from Parent to Child components via props:

// Child Component with destructured props
function ProfileCard({ name, age, isAdmin }) {
  return (
    <div className="card">
      <h2>Name: {name}</h2>
      <p>Age: {age}</p>
      {isAdmin && <span>Admin User</span>}
    </div>
  );
}

export default ProfileCard
// Using ProfileCard component in APP.Jsx / Tsx
import ProfileCard from './ProfileCard.Jsx';

function App() {
  return (
    <div>
      {/* Passing different values to the same component */}
      <ProfileCard name="Alice" age={28} isAdmin={true} />
      <ProfileCard name="Bob" age={34} isAdmin={false} />
    </div>
  );
}

Props are read-only (immutable). A child component must never modify the props it receives. If the data needs to change over time in response to user actions, put it in State.

Default Values: You can assign default parameter values right inside your destructured function arguments to handle missing values gracefully.

function Button({ text = "Click Me", color = "blue" }) {
  return <button style={{ backgroundColor: color }}>{text}</button>;
}

5. State in React

What is State?

While props allow a parent to pass data down to a child, state is a component's personal memory. State holds data that changes over time based on user interaction, network responses, or timers.

Local Component State (useState)

React provides a hook called useState to attach local state to a function component:

import { useState } from 'react';

function LikeButton() {
  // Declare a state variable named 'likes' initialized to 0
  const [likes, setLikes] = useState(0);

  function handleClick() {
    setLikes(likes + 1); // Updating state
  }

  return (
    <button onClick={handleClick}>
      ❤️ Likes: {likes}
    </button>
  );
}

State-Driven UI

In React, you don't update DOM elements manually when data changes. You simply update the state, and React automatically updates the UI to reflect the new state.

6. Understanding Re-rendering

What Causes a Re-render?

A re-render occurs when React calls a component function again to determine what changes need to be made on screen. The primary triggers for a re-render are:

  1. State updates: Calling a state updater function (e.g., setLikes).
  2. Prop changes: When a parent component passes new prop values down to a child.
  3. Parent re-rendering: When a parent component re-renders, all its child components re-render by default.

The Mental Model for Re-rendering

  1. Trigger: User clicks a button, triggering a state update.
  2. Render: React runs the component function to get the updated JSX structure.
  3. Commit: React compares the new JSX with the previous render (diffing) and updates only the modified parts of the actual browser DOM.

7. React's Declarative Nature

Imperative vs Declarative

  • Imperative (Vanilla JS): Focuses on how to achieve a result, step by step.

    "Find button #1, listen for click, get text box #2, read text, create new <li>, append <li> to list #3."

  • Declarative (React): Focuses on what the final UI should look like based on the current state.

    "Here is an array of items in state. Render an <li> for every item in this array."

Predictable UI Updates

By declaring what the UI should look like for state \(S_1\) versus state \(S_2\), React eliminates bugs caused by forgotten DOM updates or inconsistent UI states.

8. Component Tree Architecture

React applications are structured as a hierarchy of components:

App
 ├── Header
 │    └── UserProfile
 └── Dashboard
      ├── Widget (Users)
      ├── Widget (Revenue)
      └── ProductCardList
           ├── ProductCard
           └── ProductCard
  • Data Flow: Data flows unidirectionally downwards from parent components to child components via props.
  • Component Hierarchy: Keeps application structure modular, organized, and scalable.

9. Common Beginner Mistakes

  1. Mutating State Directly:
    • ❌ state.count = 5; (React will not detect this change or trigger a re-render).
    • ✅ setCount(5);
  2. Confusing Props and State:
    • Props: Passed into a component from above (read-only).
    • State: Managed inside the component (mutable via state setter).
  3. Overusing State:
    • Do not put values into state if they can be calculated on the fly during rendering (e.g., calculating fullName from firstName and lastName).
  4. Creating Monolithic Components:
    • Keeping hundreds of lines of UI and logic in a single file instead of breaking them into smaller sub-components.

10. Building Applications with Components

When building an application in React, use the Thinking in React methodology:

  1. Break the UI into a Component Hierarchy: Draw boxes around every component and subcomponent in your mockups.
  2. Build a Static Version in React: Create components that take props and render UI without adding state yet.
  3. Identify the Minimal Representation of UI State: Figure out the absolute minimum state your application needs.
  4. Determine Where Your State Should Live: Identify which component owns or holds the state.
  5. Add Inverse Data Flow: Pass down callback functions through props so child components can request state changes from parents.

If you want to practice or prepare for a React interview, or are just learning, I highly recommend you check out React Labs by Chaicode.com

3 views

About the author

  • I'm a full-stack developer passionate about building scalable, real-world applications from the ground up. My expertise spans the entire web development stack, from crafting semantic HTML and responsive layouts with modern CSS (Flexbox, Grid, Tailwind) to building dynamic interfaces with React, TypeScript, and Next.js.

No comments yet. Be the first to comment.