React Cheatsheet: HTML Rendering and Core Concepts

React Cheatsheet: HTML Rendering and Core Concepts

What Is React?

React is a JavaScript library developed by Facebook (Meta) for building user interfaces. It uses a component-based architecture where the UI is broken into independent, reusable pieces that each manage their own logic and appearance. React uses a virtual DOM to efficiently update only the parts of the real DOM that have changed, making it fast even for complex UIs.

JSX: JavaScript + HTML

JSX is a syntax extension that looks like HTML but compiles to JavaScript function calls. Every JSX expression must have a single root element:

// Valid JSX
const element = (
  <div className="container">
    <h1>Hello, {name}!</h1>
    <p>Welcome to React.</p>
  </div>
);

// Use fragments to avoid extra DOM nodes
const element = (
  <>
    <h1>Title</h1>
    <p>Paragraph</p>
  </>
);

Key JSX differences from HTML: | HTML | JSX | |---|---| | class="..." | className="..." | | for="..." | htmlFor="..." | | <input /> self-closing | Same, but required | | onclick="..." | onClick={handler} | | Inline styles as strings | Inline styles as objects |

// Inline styles in JSX
<div style={{ backgroundColor: 'blue', fontSize: '16px' }}>
  Styled element
</div>

Functional Components

The modern way to write React components:

// Basic functional component
function Greeting({ name, age }) {
  return (
    <div>
      <h1>Hello, {name}!</h1>
      <p>You are {age} years old.</p>
    </div>
  );
}

// Arrow function syntax
const Greeting = ({ name, age }) => (
  <div>
    <h1>Hello, {name}!</h1>
    <p>You are {age} years old.</p>
  </div>
);

// Usage
<Greeting name="Alice" age={30} />

Props

Props are read-only data passed from parent to child components:

// Passing various prop types
<UserCard
  name="Alice"                    // String
  age={30}                        // Number (use curly braces)
  isActive={true}                 // Boolean
  hobbies={['reading', 'coding']} // Array
  address={{ city: 'NYC' }}       // Object
  onClick={handleClick}           // Function
/>

// Default props
function Button({ label = 'Click me', variant = 'primary' }) {
  return <button className={variant}>{label}</button>;
}

// Spreading props
const buttonProps = { label: 'Submit', disabled: false };
<Button {...buttonProps} />

// Children prop
function Card({ children, title }) {
  return (
    <div className="card">
      <h2>{title}</h2>
      <div className="card-body">{children}</div>
    </div>
  );
}

// Usage with children
<Card title="My Card">
  <p>This is the card content.</p>
</Card>

useState Hook

Manages local component state:

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
      <button onClick={() => setCount(c => c - 1)}>-</button>
      <button onClick={() => setCount(0)}>Reset</button>
    </div>
  );
}

// Object state
const [user, setUser] = useState({ name: '', email: '' });
// Always spread to avoid overwriting other fields
setUser(prev => ({ ...prev, name: 'Alice' }));

// Array state
const [items, setItems] = useState([]);
setItems(prev => [...prev, newItem]);           // Add
setItems(prev => prev.filter(i => i.id !== id)); // Remove
setItems(prev => prev.map(i => i.id === id ? {...i, ...changes} : i)); // Update

useEffect Hook

Handles side effects (data fetching, subscriptions, DOM manipulation):

import { useState, useEffect } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // Runs after every render (no dependency array)
    // document.title = 'Hello';
  });

  useEffect(() => {
    // Runs once on mount (empty dependency array)
    console.log('Component mounted');
    return () => console.log('Component unmounted'); // Cleanup
  }, []);

  useEffect(() => {
    // Runs when userId changes
    setLoading(true);
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => {
        setUser(data);
        setLoading(false);
      });
  }, [userId]); // Dependency array

  if (loading) return <p>Loading...</p>;
  return <div>{user?.name}</div>;
}

Event Handling

function Form() {
  const [value, setValue] = useState('');

  // Synthetic events work just like native DOM events
  const handleChange = (e) => setValue(e.target.value);
  const handleSubmit = (e) => {
    e.preventDefault(); // Prevent page reload
    console.log('Submitted:', value);
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="text"
        value={value}
        onChange={handleChange}
        onFocus={() => console.log('Focused')}
        onBlur={() => console.log('Blurred')}
      />
      <button type="submit">Submit</button>
    </form>
  );
}

Conditional Rendering

function Status({ isLoggedIn, role }) {
  // Ternary operator
  return <div>{isLoggedIn ? <UserMenu /> : <LoginButton />}</div>;
}

// Short-circuit evaluation (render nothing if false)
{isLoggedIn && <UserMenu />}

// Null to render nothing
if (!data) return null;

// Multiple conditions
function Badge({ role }) {
  if (role === 'admin') return <span className="admin">Admin</span>;
  if (role === 'mod') return <span className="mod">Moderator</span>;
  return <span>User</span>;
}

Lists and Keys

function TodoList({ todos }) {
  return (
    <ul>
      {todos.map(todo => (
        // Key must be unique among siblings, stable, and not index if list reorders
        <li key={todo.id} className={todo.done ? 'done' : ''}>
          {todo.text}
        </li>
      ))}
    </ul>
  );
}

useContext: Avoiding Prop Drilling

import { createContext, useContext, useState } from 'react';

const ThemeContext = createContext('light');

function App() {
  const [theme, setTheme] = useState('light');
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function ThemedButton() {
  const { theme, setTheme } = useContext(ThemeContext);
  return (
    <button
      style={{ background: theme === 'dark' ? '#333' : '#fff' }}
      onClick={() => setTheme(t => t === 'light' ? 'dark' : 'light')}
    >
      Toggle Theme
    </button>
  );
}

useRef Hook

import { useRef, useEffect } from 'react';

function TextInput() {
  const inputRef = useRef(null);

  useEffect(() => {
    inputRef.current.focus(); // Focus on mount
  }, []);

  // Store mutable value without causing re-render
  const renderCount = useRef(0);
  renderCount.current += 1;

  return <input ref={inputRef} />;
}

Custom Hooks

Extract reusable stateful logic into custom hooks (functions starting with use):

function useFetch(url) {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    const controller = new AbortController();
    fetch(url, { signal: controller.signal })
      .then(res => res.json())
      .then(setData)
      .catch(err => { if (err.name !== 'AbortError') setError(err); })
      .finally(() => setLoading(false));
    return () => controller.abort();
  }, [url]);

  return { data, loading, error };
}

// Usage
const { data: users, loading } = useFetch('/api/users');

Quick Reference Summary

HookPurpose
useStateLocal component state
useEffectSide effects (fetch, subscriptions)
useContextConsume context without prop drilling
useRefDOM references, mutable values
useMemoMemoize expensive computations
useCallbackMemoize function references
useReducerComplex state logic
Share: