Bird
Raised Fist0
NextJSframework~20 mins

Zustand for client state in NextJS - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Zustand Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What is the output of this Zustand store usage?
Consider this Zustand store and component code in a Next.js app. What will the component display when rendered?
NextJS
import create from 'zustand';

const useStore = create(set => ({
  count: 0,
  increment: () => set(state => ({ count: state.count + 1 }))
}));

export default function Counter() {
  const { count, increment } = useStore();
  return (
    <>
      <p>Count: {count}</p>
      <button onClick={increment}>Add</button>
    </>
  );
}
AThe component shows 'Count: 0' initially and increments count by 1 each time the button is clicked.
BThe component shows 'Count: 1' initially and increments count by 1 each time the button is clicked.
CThe component shows 'Count: 0' but clicking the button does not change the count.
DThe component throws a runtime error because the store is not initialized.
Attempts:
2 left
💡 Hint
Remember Zustand's create function initializes state and actions. The initial count is 0.
❓ state_output
intermediate
2:00remaining
What is the value of count after these actions?
Given this Zustand store and sequence of actions, what is the final value of count?
NextJS
import create from 'zustand';

const useStore = create(set => ({
  count: 5,
  increment: () => set(state => ({ count: state.count + 1 })),
  reset: () => set({ count: 0 })
}));

// Actions executed in order:
// 1. increment()
// 2. increment()
// 3. reset()
// 4. increment()
A3
B0
C2
D1
Attempts:
2 left
💡 Hint
Apply each action step-by-step starting from count = 5.
📝 Syntax
advanced
2:00remaining
Which option correctly creates a Zustand store with a toggle boolean?
You want to create a Zustand store with a boolean state 'isOpen' and a toggle function that flips its value. Which code is correct?
Aconst useStore = create(set => ({ isOpen: false, toggle: () => set(state => { isOpen = !state.isOpen }) }));
Bconst useStore = create(set => ({ isOpen: false, toggle: () => set(state => ({ isOpen: !state.isOpen })) }));
Cconst useStore = create(set => ({ isOpen: false, toggle: () => set({ isOpen: !isOpen }) }));
Dconst useStore = create({ isOpen: false, toggle: () => set(state => ({ isOpen: !state.isOpen })) });
Attempts:
2 left
💡 Hint
Remember the create function expects a function with set parameter returning an object.
🔧 Debug
advanced
2:00remaining
Why does this Zustand store not update the component on state change?
Given this store and component, why does the component not re-render when the button is clicked?
NextJS
import create from 'zustand';

const useStore = create(set => ({
  count: 0,
  increment: () => set({ count: count + 1 })
}));

export default function Counter() {
  const count = useStore(state => state.count);
  const increment = useStore(state => state.increment);
  return (
    <>
      <p>{count}</p>
      <button onClick={increment}>Add</button>
    </>
  );
}
AThe component does not subscribe to the store, so it never re-renders.
BThe set function is missing in the store creation, so state cannot update.
CThe increment function uses 'count' variable which is undefined in its scope, so state never updates.
DThe button's onClick handler is not correctly assigned, so increment is never called.
Attempts:
2 left
💡 Hint
Check how the increment function accesses the current count value.
🧠 Conceptual
expert
2:00remaining
Which statement about Zustand and Next.js client state is true?
Select the correct statement about using Zustand for client state management in a Next.js app.
AZustand stores are client-side only and should not be used to share state between server and client without hydration handling.
BZustand stores should be created inside React components to isolate state per component instance.
CZustand stores are global and persist across server and client rendering automatically without extra setup.
DZustand requires wrapping the Next.js app with a provider component to work correctly.
Attempts:
2 left
💡 Hint
Think about how Zustand manages state and Next.js rendering phases.

Practice

(1/5)
1. What is the main purpose of using zustand in a Next.js app?
easy
A. To manage and share client-side state easily across components
B. To handle server-side rendering automatically
C. To style components with CSS-in-JS
D. To fetch data from external APIs

Solution

  1. Step 1: Understand Zustand's role

    Zustand is a small library designed to manage state on the client side simply and clearly.
  2. Step 2: Compare options with Zustand's purpose

    Only To manage and share client-side state easily across components matches Zustand's main use: managing and sharing client state across components.
  3. Final Answer:

    To manage and share client-side state easily across components -> Option A
  4. Quick Check:

    Zustand = client state management [OK]
Hint: Zustand is for client state, not styling or server tasks [OK]
Common Mistakes:
  • Confusing Zustand with data fetching libraries
  • Thinking Zustand handles styling
  • Assuming Zustand manages server rendering
2. Which of the following is the correct way to create a Zustand store in Next.js?
easy
A. const useStore = createStore((get) => ({ count: 0, increment: () => get(state => state.count + 1) }))
B. const useStore = createStore({ count: 0, increment() { this.count++ } })
C. const useStore = new Zustand({ count: 0, increment() { this.count++ } })
D. const useStore = create((set) => ({ count: 0, increment: () => set(state => ({ count: state.count + 1 })) }))

Solution

  1. Step 1: Recall Zustand store creation syntax

    Zustand uses the create function with a callback receiving set to update state.
  2. Step 2: Check each option's syntax

    const useStore = create((set) => ({ count: 0, increment: () => set(state => ({ count: state.count + 1 })) })) correctly uses create with set and updates state immutably. Others use invalid or non-existent APIs.
  3. Final Answer:

    const useStore = create((set) => ({ count: 0, increment: () => set(state => ({ count: state.count + 1 })) })) -> Option D
  4. Quick Check:

    Use create + set callback = const useStore = create((set) => ({ count: 0, increment: () => set(state => ({ count: state.count + 1 })) })) [OK]
Hint: Zustand store uses create() with set callback [OK]
Common Mistakes:
  • Using createStore instead of create
  • Trying to mutate state directly
  • Confusing get and set functions
3. Given this Zustand store code:
const useStore = create(set => ({ count: 0, increment: () => set(state => ({ count: state.count + 1 })) }));
useStore.getState().increment();
console.log(useStore.getState().count);

What will be logged to the console?
medium
A. 1
B. Error
C. undefined
D. 0

Solution

  1. Step 1: Understand initial state and increment call

    The store starts with count = 0. Calling increment() increases count by 1.
  2. Step 2: Check console.log output

    After increment(), count becomes 1, so logging count outputs 1.
  3. Final Answer:

    1 -> Option A
  4. Quick Check:

    Increment changes count 0 -> 1 [OK]
Hint: Increment adds 1, so count becomes 1 [OK]
Common Mistakes:
  • Assuming state doesn't update immediately
  • Confusing getState() with useStore() hook
  • Expecting initial value without increment
4. Identify the error in this Zustand store code:
const useStore = create(set => ({
count: 0,
increment() {
this.count += 1;
}
}));
medium
A. Missing initial state declaration
B. Using this inside increment does not update Zustand state
C. The create function is not imported
D. The increment function should be async

Solution

  1. Step 1: Analyze increment function behavior

    Using this.count += 1 tries to mutate the object directly, which does not update Zustand's internal state.
  2. Step 2: Understand correct state update in Zustand

    Zustand requires calling set to update state immutably; direct mutation won't trigger updates.
  3. Final Answer:

    Using this inside increment does not update Zustand state -> Option B
  4. Quick Check:

    Direct mutation with this = no state update [OK]
Hint: Always use set() to update Zustand state, not this [OK]
Common Mistakes:
  • Mutating state directly with this
  • Forgetting to import create
  • Thinking async is needed for increment
5. You want to create a Zustand store that holds a list of tasks and a function to add a new task only if it is not empty. Which code snippet correctly implements this logic?
hard
A. const useStore = create(set => ({ tasks: [], addTask: (task) => set(state => ({ tasks: [...state.tasks, task] })) }))
B. const useStore = create(set => ({ tasks: [], addTask: (task) => { if (!task) set(state => ({ tasks: [...state.tasks, task] })) } }))
C. const useStore = create(set => ({ tasks: [], addTask: (task) => { if (!task) return; set(state => ({ tasks: [...state.tasks, task] })) } }))
D. const useStore = create(set => ({ tasks: [], addTask: (task) => set(state => { if (!task) return { tasks: [...state.tasks, task] } else return state }) }))

Solution

  1. Step 1: Understand the requirement to add task only if not empty

    The function must check if the task is empty and skip adding if so.
  2. Step 2: Analyze each option's logic

    const useStore = create(set => ({ tasks: [], addTask: (task) => set(state => ({ tasks: [...state.tasks, task] })) })) adds unconditionally.
    const useStore = create(set => ({ tasks: [], addTask: (task) => { if (!task) set(state => ({ tasks: [...state.tasks, task] })) } })) adds only if !task (when empty).
    const useStore = create(set => ({ tasks: [], addTask: (task) => set(state => { if (!task) return { tasks: [...state.tasks, task] } else return state }) })) adds only if !task inside the set updater.
    const useStore = create(set => ({ tasks: [], addTask: (task) => { if (!task) return; set(state => ({ tasks: [...state.tasks, task] })) } })) correctly returns early if !task (empty), then calls set to add non-empty task.
  3. Final Answer:

    const useStore = create(set => ({ tasks: [], addTask: (task) => { if (!task) return; set(state => ({ tasks: [...state.tasks, task] })) } })) -> Option C
  4. Quick Check:

    Early return on empty task + set call = const useStore = create(set => ({ tasks: [], addTask: (task) => { if (!task) return; set(state => ({ tasks: [...state.tasks, task] })) } })) [OK]
Hint: Return early if empty, then call set to update state [OK]
Common Mistakes:
  • Adding tasks without checking if empty
  • Misusing set callback with conditional returns
  • Not returning early to prevent adding empty tasks
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard