ENGIMY.IO - CHEATSHEET
REACT × QUICK REFERENCE
REFERENCE vReact 18

React Quick Reference

Everything you need day‑to‑day – components, hooks, state, routing, and best practices.

JSX

// Basic JSX
const element = <h1>Hello, world!</h1>;

// Embedding expressions
const name = "Alice";
const element = <h1>Hello, {name}!</h1>;

// Attributes
const img = <img src={imageUrl} alt="Description" />;

// Class vs className (use className)
const div = <div className="container">Content</div>;

// Inline styles (camelCase)
const div = <div style={{ color: 'red', fontSize: '16px' }}>Content</div>;

// Fragments (no extra DOM node)
<React.Fragment>
  <h1>Title</h1>
  <p>Content</p>
</React.Fragment>

// Short syntax
<>
  <h1>Title</h1>
  <p>Content</p>
</>

Components

Functional Component

function Greeting({ name }) {
    return <h1>Hello, {name}!</h1>;
}

// Arrow function
const Greeting = ({ name }) => {
    return <h1>Hello, {name}!</h1>;
};

Component with Props

function UserCard({ name, age, email, children }) {
    return (
        <div className="card">
            <h2>{name}</h2>
            <p>Age: {age}</p>
            <p>Email: {email}</p>
            {children}
        </div>
    );
}

// Usage
<UserCard name="Alice" age={25} email="alice@example.com">
    <p>Additional content</p>
</UserCard>

Default Props

function Greeting({ name = "Guest" }) {
    return <h1>Hello, {name}!</h1>;
}

// Alternative
Greeting.defaultProps = {
    name: "Guest"
};

State Management

useState

import { useState } from 'react';

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

    const increment = () => setCount(count + 1);
    const decrement = () => setCount(count - 1);

    return (
        <div>
            <p>Count: {count}</p>
            <button onClick={increment}>+</button>
            <button onClick={decrement}>-</button>
        </div>
    );
}

// Functional update (when next state depends on previous)
setCount(prev => prev + 1);

// Object state
const [user, setUser] = useState({ name: '', age: 0 });
setUser(prev => ({ ...prev, age: prev.age + 1 }));

Lifting State Up

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

    return (
        <div>
            <Child count={count} setCount={setCount} />
        </div>
    );
}

function Child({ count, setCount }) {
    return (
        <button onClick={() => setCount(count + 1)}>
            Increment: {count}
        </button>
    );
}

Effects (useEffect)

import { useEffect } from 'react';

function Example() {
    useEffect(() => {
        // Runs after every render (by default)
        console.log("Component rendered");

        // Cleanup (optional)
        return () => {
            console.log("Cleanup");
        };
    });

    // Runs only on mount (empty dependency array)
    useEffect(() => {
        console.log("Mounted");
    }, []);

    // Runs when count changes
    useEffect(() => {
        console.log("Count changed:", count);
    }, [count]);

    // Runs when count OR name changes
    useEffect(() => {
        console.log("Count or name changed");
    }, [count, name]);

    return <div>Example</div>;
}

Refs (useRef)

import { useRef, useEffect } from 'react';

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

    useEffect(() => {
        inputRef.current.focus();
    }, []);

    return <input ref={inputRef} type="text" />;
}

// Mutable ref (persists between renders)
function Timer() {
    const countRef = useRef(0);

    const increment = () => {
        countRef.current++;
        console.log(countRef.current);
    };

    return <button onClick={increment}>Increment</button>;
}

Memoization

useMemo

import { useMemo, useState } from 'react';

function ExpensiveComponent({ numbers }) {
    const [filter, setFilter] = useState('');

    // Only recompute when numbers changes
    const total = useMemo(() => {
        console.log("Calculating total...");
        return numbers.reduce((sum, n) => sum + n, 0);
    }, [numbers]);

    return <div>Total: {total}</div>;
}

useCallback

import { useCallback, useState } from 'react';

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

    // Only recreated when count changes
    const handleClick = useCallback(() => {
        console.log("Clicked", count);
    }, [count]);

    return <Child onClick={handleClick} />;
}

// React.memo – prevent re‑rendering if props unchanged
const Child = React.memo(({ onClick }) => {
    console.log("Child rendered");
    return <button onClick={onClick}>Click</button>;
});

Context API

// Create context
const ThemeContext = React.createContext('light');

// Provider
function App() {
    const [theme, setTheme] = useState('light');

    return (
        <ThemeContext.Provider value={{ theme, setTheme }}>
            <Toolbar />
        </ThemeContext.Provider>
    );
}

// Consumer (useContext hook)
function Toolbar() {
    const { theme, setTheme } = useContext(ThemeContext);

    return (
        <div style={{ background: theme === 'dark' ? '#333' : '#fff' }}>
            <button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>
                Toggle Theme
            </button>
        </div>
    );
}

Event Handling

function Button() {
    // Basic handler
    const handleClick = (event) => {
        console.log("Clicked!", event);
    };

    // With parameter
    const handleDelete = (id) => {
        console.log("Deleting:", id);
    };

    return (
        <div>
            <button onClick={handleClick}>Click</button>
            <button onClick={() => handleDelete(123)}>Delete</button>

            // Form submit (prevent default)
            <form onSubmit={(e) => {
                e.preventDefault();
                console.log("Submitted");
            }}>
                <input type="text" />
                <button type="submit">Submit</button>
            </form>
        </div>
    );
}

Conditional Rendering

// If with ternary
function Greeting({ isLoggedIn }) {
    return (
        <div>
            {isLoggedIn ? <LogoutButton /> : <LoginButton />}
        </div>
    );
}

// If with logical && (render if true)
function Notification({ message }) {
    return <div>{message && <p>{message}</p>}</div>;
}

// Early return
function User({ user }) {
    if (!user) return <p>Loading...</p>;
    return <p>Hello, {user.name}</p>;
}

Lists & Keys

function TodoList({ todos }) {
    return (
        <ul>
            {todos.map((todo) => (
                <li key={todo.id}>{todo.text}</li>
            ))}
        </ul>
    );
}

// Keys should be stable, unique, and predictable
// Use id from data, not array index (unless list is static)

Forms (Controlled Components)

import { useState } from 'react';

function LoginForm() {
    const [formData, setFormData] = useState({
        email: '',
        password: '',
        remember: false
    });

    const handleChange = (e) => {
        const { name, value, type, checked } = e.target;
        setFormData(prev => ({
            ...prev,
            [name]: type === 'checkbox' ? checked : value
        }));
    };

    const handleSubmit = (e) => {
        e.preventDefault();
        console.log("Form data:", formData);
    };

    return (
        <form onSubmit={handleSubmit}>
            <input
                type="email"
                name="email"
                value={formData.email}
                onChange={handleChange}
                placeholder="Email"
            />
            <input
                type="password"
                name="password"
                value={formData.password}
                onChange={handleChange}
                placeholder="Password"
            />
            <label>
                <input
                    type="checkbox"
                    name="remember"
                    checked={formData.remember}
                    onChange={handleChange}
                />
                Remember me
            </label>
            <button type="submit">Login</button>
        </form>
    );
}

React Router

import { BrowserRouter, Routes, Route, Link, useParams, useNavigate } from 'react-router-dom';

// Setup
function App() {
    return (
        <BrowserRouter>
            <nav>
                <Link to="/">Home</Link>
                <Link to="/about">About</Link>
                <Link to="/users">Users</Link>
            </nav>
            <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/about" element={<About />} />
                <Route path="/users" element={<Users />} />
                <Route path="/users/:id" element={<UserDetail />} />
                <Route path="*" element={<NotFound />} />
            </Routes>
        </BrowserRouter>
    );
}

// Using params
function UserDetail() {
    const { id } = useParams();
    return <p>User ID: {id}</p>;
}

// Navigation
function Profile() {
    const navigate = useNavigate();
    return (
        <button onClick={() => navigate('/settings')}>
            Go to Settings
        </button>
    );
}

// Navigation with state
navigate('/profile', { state: { userId: 123 } });

Custom Hooks

// useLocalStorage
function useLocalStorage(key, initialValue) {
    const [value, setValue] = useState(() => {
        const stored = localStorage.getItem(key);
        return stored ? JSON.parse(stored) : initialValue;
    });

    useEffect(() => {
        localStorage.setItem(key, JSON.stringify(value));
    }, [key, value]);

    return [value, setValue];
}

// Usage
function App() {
    const [name, setName] = useLocalStorage('name', 'Guest');
    return <input value={name} onChange={(e) => setName(e.target.value)} />;
}

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

    useEffect(() => {
        fetch(url)
            .then(res => res.json())
            .then(data => {
                setData(data);
                setLoading(false);
            })
            .catch(err => {
                setError(err);
                setLoading(false);
            });
    }, [url]);

    return { data, loading, error };
}

Styling

Inline Styles

const style = {
    color: 'red',
    fontSize: '16px',
    fontWeight: 'bold'
};
<div style={style}>Content</div>

CSS Modules

// Component.module.css
.container { display: flex; }
.title { font-size: 24px; }

// Component.jsx
import styles from './Component.module.css';
<div className={styles.container}>
    <h1 className={styles.title}>Title</h1>
</div>

Styled Components

import styled from 'styled-components';

const Button = styled.button`
    background: ${props => props.primary ? 'blue' : 'gray'};
    color: white;
    padding: 10px 20px;
    border: none;
    border-radius: 4px;
    cursor: pointer;

    &:hover {
        opacity: 0.8;
    }
`;

<Button primary>Click me</Button>

useReducer

import { useReducer } from 'react';

function reducer(state, action) {
    switch (action.type) {
        case 'INCREMENT':
            return { count: state.count + 1 };
        case 'DECREMENT':
            return { count: state.count - 1 };
        case 'RESET':
            return { count: 0 };
        default:
            return state;
    }
}

function Counter() {
    const [state, dispatch] = useReducer(reducer, { count: 0 });

    return (
        <div>
            <p>Count: {state.count}</p>
            <button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
            <button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button>
            <button onClick={() => dispatch({ type: 'RESET' })}>Reset</button>
        </div>
    );
}

Best Practices

  • Use functional components and hooks – class components are legacy.
  • Keep components small and focused on a single responsibility.
  • Use useMemo and useCallback for expensive calculations and stable callbacks.
  • Use React.memo to prevent unnecessary re‑renders of pure components.
  • Use useEffect with proper dependency arrays to avoid infinite loops.
  • Avoid inline functions in render for performance (use useCallback).
  • Use key correctly in lists – use stable, unique IDs.
  • Keep state as low as possible – avoid global state unless necessary.
  • Use Context for themes, user data, and other global state.
  • Use React.StrictMode to catch potential issues.
  • Write tests using React Testing Library.
  • Use eslint-plugin-react for best practices and linting.
  • Use prop-types or TypeScript for type safety.
  • Use lazy and Suspense for code splitting.
  • Use React Developer Tools for debugging.
📌 Quick Reference
Create React App: npx create-react-app my-app
Start dev server: npm start
Build for production: npm run build
Install React Router: npm install react-router-dom
← Back to All Cheatsheets