Skip to content
GeeksSmith
advanced 10 min read

State Management Architecture: Client vs Server State

Modern frontend state architecture separates Client State (ephemeral UI state like modals and forms) from Server State (asynchronous remote data requiring caching, deduplication, and invalidation).

Why it matters in interviews

Shoving asynchronous API data into global Redux or Context creates massive boilerplate, synchronization bugs, and memory bloat. Choosing the right state tier is a mandatory evaluation topic in Lead & Staff interviews.

Visual & Interactive Explanation

Interactive Flow Execution

Code Examples & Implementation

Optimistic Mutation with Automatic Rollback (TanStack Query pattern)
import { useMutation, useQueryClient } from '@tanstack/react-query';

interface Todo {
  id: string;
  title: string;
  completed: boolean;
}

export function useUpdateTodo() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (updatedTodo: Todo) => {
      const res = await fetch(`/api/todos/${updatedTodo.id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(updatedTodo),
      });
      if (!res.ok) throw new Error('Update failed');
      return res.json();
    },

    // 1. When mutation starts: snapshot previous cache & optimistically update UI
    onMutate: async (newTodo) => {
      await queryClient.cancelQueries({ queryKey: ['todos'] });
      const previousTodos = queryClient.getQueryData<Todo[]>(['todos']);

      // Optimistically update cache instantly
      queryClient.setQueryData<Todo[]>(['todos'], (old) =>
        old ? old.map((t) => (t.id === newTodo.id ? newTodo : t)) : []
      );

      return { previousTodos };
    },

    // 2. If API fails: rollback to snapshot
    onError: (err, newTodo, context) => {
      if (context?.previousTodos) {
        queryClient.setQueryData(['todos'], context.previousTodos);
      }
    },

    // 3. Always revalidate to ensure client matches database
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['todos'] });
    },
  });
}

Interview-Ready Answers

Separate Server State from Client State. Use TanStack Query for remote API data (caching, deduplication, retries), URL search params for bookmarkable filters, and Zustand or useState/Context for local/shared UI state.

Official Documentation & Specifications

Follow-up Questions & Deep Dives

🎯 Code Output — What Does This Print?

Question 1hard
const ThemeContext = React.createContext("light");

function App() {
  const [theme, setTheme] = useState("light");
  console.log("App render");
  return (
    <ThemeContext.Provider value={theme}>
      <Sidebar />
      <button onClick={() => setTheme("dark")}>Toggle</button>
    </ThemeContext.Provider>
  );
}

function Sidebar() {
  console.log("Sidebar render");
  return <Profile />;
}

function Profile() {
  const theme = useContext(ThemeContext);
  console.log("Profile render:", theme);
  return <p>{theme}</p>;
}
// User clicks Toggle. What logs?
Question 2medium
// Zustand store
const useStore = create((set) => ({
  count: 0,
  name: "Alice",
  increment: () => set((s) => ({ count: s.count + 1 })),
}));

function Counter() {
  const count = useStore((s) => s.count);
  console.log("Counter render");
  return <p>{count}</p>;
}

function Name() {
  const name = useStore((s) => s.name);
  console.log("Name render");
  return <p>{name}</p>;
}
// User calls increment(). What logs?

Common Mistakes & Anti-Patterns

  • Storing remote API response data in global Redux/Zustand and manually managing loading, error, and stale flags.
  • Passing a single monolithic object to Context.Provider without splitting contexts or memoizing values.
  • Forgetting to cancel in-flight queries before applying optimistic cache updates.

Real-World Architectural Scenario

A collaborative Kanban board with 20 teams suffers severe typing lag when updating task status. Investigation reveals all 50 board columns subscribe to a single BoardContext. How do you re-architect it?

Rate Your Readiness

Rate how comfortably you can explain this in an interview to update your global readiness gauge:

Rate your confidence: