← Back to Tutorials Chapter 10

Advanced React Concepts

Accessibility (a11y)

React fully supports HTML ARIA attributes. Use aria-* attributes on JSX elements just like in HTML. Manage focus with useRef and the tabIndex prop.

function Modal({ isOpen, onClose }) {
  const closeRef = useRef(null);

  useEffect(() => {
    if (isOpen) closeRef.current?.focus();
  }, [isOpen]);

  return isOpen ? (
    <div role="dialog" aria-modal="true" aria-labelledby="modal-title">
      <h2 id="modal-title">Confirm</h2>
      <button ref={closeRef} onClick={onClose}>Close</button>
    </div>
  ) : null;
}

Code Splitting with React.lazy & Suspense

React.lazy lets you dynamically import components. Wrap them in Suspense with a fallback UI while the chunk loads.

const HeavyChart = React.lazy(() => import("./HeavyChart"));

function Dashboard() {
  return (
    <React.Suspense fallback={<div>Loading chart...</div>}>
      <HeavyChart />
    </React.Suspense>
  );
}

Error Boundaries

Error boundaries catch JavaScript errors in their child tree and display a fallback UI instead of crashing the whole app. They must be class components implementing componentDidCatch and/or getDerivedStateFromError.

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError() { return { hasError: true }; }

  componentDidCatch(error, info) {
    logErrorToService(error, info.componentStack);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong.</h1>;
    }
    return this.props.children;
  }
}

forwardRef

forwardRef lets a parent component pass a ref down to a child's DOM element.

const FancyInput = React.forwardRef((props, ref) => (
  <input ref={ref} className="fancy" {...props} />
));

// Parent
const ref = useRef();
<FancyInput ref={ref} />;
ref.current.focus();

Fragments

<>...</> or <React.Fragment> lets you group children without adding extra nodes to the DOM.

function List() {
  return (
    <>
      <dt>Term</dt>
      <dd>Definition</dd>
    </>
  );
}

Higher-Order Components (HOCs)

An HOC is a function that takes a component and returns a new component with added props or logic.

function withLogger(WrappedComponent) {
  return function Enhanced(props) {
    console.log("Rendering", WrappedComponent.name);
    return <WrappedComponent {...props} />;
  };
}

const EnhancedButton = withLogger(MyButton);

Render Props

A render prop is a function prop a component uses to render its content, sharing internal state.

function MouseTracker({ render }) {
  const [pos, setPos] = useState({ x: 0, y: 0 });
  return <div onMouseMove={(e) => setPos({ x: e.clientX, y: e.clientY })}>
    {render(pos)}
  </div>;
}

// Usage
<MouseTracker render={({ x, y }) => <h1>{x}, {y}</h1>} />
React advanced concepts diagram

Performance: React.memo, useMemo, useCallback

const ExpensiveList = React.memo(({ items }) => (
  <ul>{items.map((i) => <li key={i.id}>{i.name}</li>)}</ul>
));

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

  const sorted = useMemo(() => items.sort((a, b) => a.name.localeCompare(b.name)), [items]);
  const onRemove = useCallback((id) => removeItem(id), []);

  return <>
    <button onClick={() => setCount(c => c + 1)}>{count}</button>
    <ExpensiveList items={sorted} onRemove={onRemove} />
  </>;
}

Portals

createPortal renders children into a different DOM node, useful for modals, tooltips, and dropdowns.

import { createPortal } from "react-dom";

function Modal({ children }) {
  return createPortal(
    <div className="modal-overlay">{children}</div>,
    document.getElementById("portal-root")
  );
}

Profiler API

The Profiler component measures rendering performance of its subtree.

<Profiler
  id="Navigation"
  onRender={(id, phase, actualDuration) => {
    console.log({ id, phase, actualDuration });
  }}
>
  <Navigation />
</Profiler>

Reconciliation & Strict Mode

React's reconciliation algorithm compares the virtual DOM tree and applies minimal DOM updates. Keys (key prop) help identify which items changed. StrictMode double-invokes effects in development to surface side-effect bugs.

Exercise: Add Error Handling & Performance Tracking

  1. Create an ErrorBoundary class component that shows a retry button on error.
  2. Use React.lazy to lazy-load a heavy chart component.
  3. Wrap a navigation component in a Profiler and log render durations.
  4. Create a withAuth HOC that passes a user prop.
  5. Use createPortal to render a modal outside the root DOM hierarchy.