Jiaxi Liu (Jesse)

Master’s Graduate

Software Engineer | Scalable APIs · Web Scraping · Data Integration · Code Quality & Refactoring

Back to Blog

React and Next.js Review: Component Communication, Hooks, Routing, and Server Components

React builds UI. Next.js adds routing, layouts, server rendering, backend routes, and deployment conventions on top of React.

Component Communication

Parent-to-child communication usually happens through props.

function Child({ name }: { name: string }) {
  return <p>{name}</p>;
}

Child-to-parent communication usually happens through callback props.

function Child({ onChange }: { onChange: (value: string) => void }) {
  return <button onClick={() => onChange("next")}>Update</button>;
}

For cross-tree state, use Context or a state management library.

Common Hooks

useState manages component state.

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

useEffect handles side effects such as data fetching or event subscriptions.

useEffect(() => {
  document.title = `Count: ${count}`;
}, [count]);

useMemo caches computed values, useCallback caches function references, and useRef stores DOM nodes or persistent values.

Next.js Routing and Layouts

In the App Router, folders define routes.

app/
  blog/
    page.tsx
  blog/[slug]/
    page.tsx

layout.tsx defines shared layout for nested routes.

Client and Server Components

Components are Server Components by default. Use "use client" when you need browser state, events, or DOM APIs.

"use client";
 
export function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
}

Backend Routes

Next.js can define API endpoints through Route Handlers.

export async function GET() {
  return Response.json({ ok: true });
}

The frontend can call these endpoints with fetch.

Deeper Notes

When reviewing this topic, do not memorize names only. Focus on component communication, hooks, Next.js routing, layouts, server/client components, and API routes. If this stays at the definition level, it becomes hard to explain in interviews or apply in projects. A stronger way to study it is to place it in a concrete scenario: who calls it, where the input comes from, what happens on failure, and whether data or state can be processed twice.

  • Frontend engineering depends on state boundaries, component responsibility, data-fetching location, and interaction feedback.
  • In Next.js, distinguish server components, client components, route handlers, and layout responsibilities.
  • Optimize render scope, asset size, caching, and interaction latency before micro-optimizing code.

In a real project, use it as a decision framework: identify inputs, constraints, failure modes, and observability before choosing a specific tool or pattern. If a solution looks simple, keep asking whether it still works when scale grows, permissions change, recovery matters, and more people collaborate on it.

Practical Checklist

  • Identify where this concept sits in the system: development-time constraint, runtime behavior, infrastructure capability, or collaboration workflow.
  • Write one minimal working example and one failure example; only knowing the happy path is usually not enough.
  • Record common misuses: edge cases, permission assumptions, performance assumptions, sync/async differences, or environment differences.
  • Connect the concept to a project experience so that an interview answer can be grounded in real tradeoffs.
  • End with one sentence about tradeoff: what it gives up and what it buys.

Self-Check Questions

  1. What core problem does this topic solve?
  2. What alternatives exist, and what are their costs?
  3. Where are the most likely edge cases?
  4. How would code, tests, or monitoring prove that it is reliable?

Applied Scenario

A useful scenario is a project page or admin dashboard. Server components read stable data, client components own interaction state, forms and buttons handle user actions, and API routes or backend services perform writes. React is not about splitting everything into tiny components; it is about clear boundaries: where data comes from, who owns state, how failure is shown, and whether a component can be reused.

Common Pitfalls:

  • Making every component a client component and losing server-rendering benefits.
  • Mixing remote data, form state, and UI expansion state together.
  • Missing loading, empty, and error states.