Perguntas de entrevista sobre Zustand 2026: Gerenciamento de estado React e melhores práticas

Prepare suas entrevistas técnicas com este guia completo sobre Zustand. Descubra perguntas frequentes, padrões de middleware, comparação com Context API e melhores práticas TypeScript.

Perguntas de entrevista Zustand 2026

Zustand se tornou a biblioteca de gerenciamento de estado preferida para aplicações React que precisam de mais do que a Context API, mas menos cerimônia do que o Redux. Com sua API minimalista e design TypeScript-first, perguntas sobre Zustand aparecem regularmente em entrevistas frontend, particularmente para posições React de nível intermediário e sênior.

O que os entrevistadores procuram

As perguntas de entrevista sobre Zustand avaliam três áreas: compreensão do padrão store versus o estado nativo do React, conhecimento de quando o Zustand supera as alternativas, e capacidade de estruturar stores para manutenibilidade.

Conceitos fundamentais do Zustand que todo candidato deve conhecer

Zustand v5, lançado no final de 2024, introduziu várias mudanças importantes em relação à v4. A função create não requer mais uma chamada separada ao useStore, e o middleware persist agora usa um modelo de hidratação síncrona por padrão. Os entrevistadores esperam que os candidatos conheçam a API atual.

O que torna o Zustand diferente de useState e useReducer?

As stores do Zustand existem fora da árvore de componentes React. Essa diferença arquitetural tem três consequências práticas:

  1. O estado persiste entre montagens e desmontagens de componentes sem providers de Context
  2. Atualizações não disparam re-renderizações em componentes pai, apenas componentes inscritos se re-renderizam
  3. O estado pode ser acessado sincronamente fora do React, útil para handlers de eventos e lógica assíncrona
store.tstypescript
import { create } from 'zustand'

interface CartStore {
  items: CartItem[]
  addItem: (item: CartItem) => void
  clearCart: () => void
  totalPrice: () => number
}

export const useCartStore = create<CartStore>((set, get) => ({
  items: [],
  addItem: (item) => set((state) => ({ 
    items: [...state.items, item] 
  })),
  clearCart: () => set({ items: [] }),
  totalPrice: () => get().items.reduce((sum, item) => sum + item.price, 0)
}))

A função get fornece acesso síncrono ao estado atual, evitando o problema de closure obsoleta comum com useState.

Como o Zustand lida com re-renderizações?

O Zustand usa igualdade superficial por padrão. Quando um componente se inscreve em uma store com useCartStore(), ele recebe o objeto de estado completo e se re-renderiza em qualquer mudança. Selecionar slices específicos previne renderizações desnecessárias:

Component.tsxtypescript
// Ruim: re-renderiza em qualquer mudança na store
const { items } = useCartStore()

// Bom: re-renderiza apenas quando items muda
const items = useCartStore((state) => state.items)

// Múltiplos valores: usar comparação superficial
import { shallow } from 'zustand/shallow'

const { items, totalPrice } = useCartStore(
  (state) => ({ items: state.items, totalPrice: state.totalPrice() }),
  shallow
)

O comparador shallow de zustand/shallow realiza igualdade de referência nas propriedades do objeto em vez do objeto em si.

Zustand vs Context API: quando escolher cada um

Essa pergunta de comparação aparece em quase todas as entrevistas que cobrem gerenciamento de estado. A resposta depende da frequência de atualizações e da complexidade do estado.

CritérioContext APIZustand
Tamanho do bundle0 KB (integrado)1.2 KB gzipped
Controle de re-rendersManual com memo/useMemoSeletores integrados
DevToolsApenas React DevToolsCompatível com Redux DevTools
Server ComponentsSuporte completoRequer boundary cliente
Estado assíncronoRequer wrapperSuporte nativo

A Context API funciona bem para valores que mudam pouco frequentemente como tema ou locale. O Zustand se destaca quando atualizações de estado ocorrem frequentemente, como inputs de formulário, dados em tempo real ou carrinhos de compra. A documentação do React sobre gerenciamento de estado recomenda elevar o estado e usar Context para problemas de "prop drilling", enquanto stores externos são adequados para padrões de atualização complexos.

Consideração sobre Server Components

As stores do Zustand requerem a diretiva "use client". Para aplicações que usam React Server Components extensivamente, isso significa que o estado do Zustand vive apenas em componentes cliente. Arquiteturas híbridas frequentemente passam dados obtidos do servidor como props para componentes cliente que então sincronizam com o Zustand.

Padrões de middleware no Zustand

As perguntas sobre middleware testam se um candidato entende composição sobre configuração. Os middlewares do Zustand envolvem a função criadora da store, adicionando comportamento sem modificar a API principal.

Como o middleware persist funciona?

store.tstypescript
import { create } from 'zustand'
import { persist, createJSONStorage } from 'zustand/middleware'

interface UserPreferences {
  theme: 'light' | 'dark'
  language: string
  setTheme: (theme: 'light' | 'dark') => void
}

export const usePreferencesStore = create<UserPreferences>()(
  persist(
    (set) => ({
      theme: 'light',
      language: 'en',
      setTheme: (theme) => set({ theme })
    }),
    {
      name: 'user-preferences',
      storage: createJSONStorage(() => localStorage),
      partialize: (state) => ({ theme: state.theme, language: state.language })
    }
  )
)

A opção partialize exclui funções e estado derivado da persistência. Sem ela, a serialização falha ou o armazenamento fica inchado com dados desnecessários. A documentação do Zustand sobre persist cobre estratégias de migração para mudanças de schema.

Combinando múltiplos middleware

Os middlewares se compõem de dentro para fora. O middleware mais interno executa primeiro:

store.tstypescript
import { create } from 'zustand'
import { devtools, persist, subscribeWithSelector } from 'zustand/middleware'
import { immer } from 'zustand/middleware/immer'

export const useStore = create<StoreState>()(
  devtools(
    persist(
      subscribeWithSelector(
        immer((set) => ({
          // state and actions
        }))
      ),
      { name: 'app-storage' }
    ),
    { name: 'AppStore' }
  )
)

O middleware immer permite atualizações de estilo mutável que produzem estado imutável. O middleware subscribeWithSelector permite se inscrever em slices de estado fora dos componentes React.

Pronto para mandar bem nas entrevistas de React / Next.js?

Pratique com nossos simuladores interativos, flashcards e testes tecnicos.

Padrões de integração com TypeScript

O Zustand v5 melhorou significativamente a inferência TypeScript. O padrão de dupla chamada de função create<Type>()() fornece inferência de tipos completa para cadeias de middleware.

Tipando ações que referenciam outro estado

store.tstypescript
interface TodoStore {
  todos: Todo[]
  filter: 'all' | 'active' | 'completed'
  addTodo: (text: string) => void
  toggleTodo: (id: string) => void
  filteredTodos: () => Todo[]
}

export const useTodoStore = create<TodoStore>()((set, get) => ({
  todos: [],
  filter: 'all',
  
  addTodo: (text) => set((state) => ({
    todos: [...state.todos, { id: crypto.randomUUID(), text, completed: false }]
  })),
  
  toggleTodo: (id) => set((state) => ({
    todos: state.todos.map((todo) =>
      todo.id === id ? { ...todo, completed: !todo.completed } : todo
    )
  })),
  
  filteredTodos: () => {
    const { todos, filter } = get()
    switch (filter) {
      case 'active': return todos.filter((t) => !t.completed)
      case 'completed': return todos.filter((t) => t.completed)
      default: return todos
    }
  }
}))

Estado derivado como funções em vez de getters evita valores obsoletos. Cada chamada a filteredTodos() lê o estado atual.

Dividindo stores para aplicações grandes

Uma pergunta comum de entrevista pergunta como estruturar o Zustand para escalar. O padrão slice divide uma store em módulos por domínio:

slices/authSlice.tstypescript
import { StateCreator } from 'zustand'

export interface AuthSlice {
  user: User | null
  isAuthenticated: boolean
  login: (credentials: Credentials) => Promise<void>
  logout: () => void
}

export const createAuthSlice: StateCreator<
  AuthSlice & CartSlice,  // Tipo da store combinada
  [],
  [],
  AuthSlice
> = (set) => ({
  user: null,
  isAuthenticated: false,
  login: async (credentials) => {
    const user = await authApi.login(credentials)
    set({ user, isAuthenticated: true })
  },
  logout: () => set({ user: null, isAuthenticated: false })
})
store.tstypescript
import { create } from 'zustand'
import { createAuthSlice, AuthSlice } from './slices/authSlice'
import { createCartSlice, CartSlice } from './slices/cartSlice'

export const useStore = create<AuthSlice & CartSlice>()((...args) => ({
  ...createAuthSlice(...args),
  ...createCartSlice(...args)
}))

Os slices podem referenciar uns aos outros através do tipo de store combinada passado para StateCreator.

Perguntas comuns de entrevista com respostas modelo

Quando o Zustand seria uma má escolha?

O Zustand adiciona complexidade sem benefício nestes cenários:

  • Dados de configuração estática que nunca mudam em tempo de execução
  • Estado de formulário gerenciado por React Hook Form ou bibliotecas similares
  • Estado do servidor melhor gerenciado por TanStack Query ou SWR
  • Passagem de props simples pai-filho com 2-3 níveis de aninhamento

A seção de comparação do repositório GitHub do Zustand fornece a perspectiva dos mantenedores sobre as alternativas.

Como testar componentes que usam Zustand?

Os testes requerem resetar o estado da store entre testes e opcionalmente mockar a store completamente:

store.test.tstypescript
import { act, renderHook } from '@testing-library/react'
import { useCartStore } from './store'

beforeEach(() => {
  // Resetar a store para o estado inicial
  useCartStore.setState({ items: [], totalItems: 0 })
})

test('addItem increases cart count', () => {
  const { result } = renderHook(() => useCartStore())
  
  act(() => {
    result.current.addItem({ id: '1', name: 'Product', price: 10 })
  })
  
  expect(result.current.items).toHaveLength(1)
})

Para testes de componentes que não devem interagir com stores reais, mockar no nível do módulo:

Component.test.tsxtypescript
import { vi } from 'vitest'

vi.mock('./store', () => ({
  useCartStore: vi.fn(() => ({
    items: [{ id: '1', name: 'Mock Product', price: 25 }],
    addItem: vi.fn()
  }))
}))

Como o Zustand lida com operações assíncronas?

Diferente do Redux, o Zustand não tem requisito de middleware para async. As ações podem ser funções assíncronas diretamente:

store.tstypescript
interface ProductStore {
  products: Product[]
  isLoading: boolean
  error: string | null
  fetchProducts: () => Promise<void>
}

export const useProductStore = create<ProductStore>((set) => ({
  products: [],
  isLoading: false,
  error: null,
  
  fetchProducts: async () => {
    set({ isLoading: true, error: null })
    try {
      const products = await productApi.getAll()
      set({ products, isLoading: false })
    } catch (err) {
      set({ error: err.message, isLoading: false })
    }
  }
}))

Para fluxos assíncronos complexos, o guia de padrões async do Zustand recomenda manter os estados de loading e error colocalizados com os dados que descrevem.

Mudanças do Zustand v5 que podem aparecer em entrevistas

O Zustand v5 introduziu mudanças importantes que os entrevistadores usam para avaliar se os candidatos se mantêm atualizados:

  • Sem mais exports padrão: Importar { create } em vez de create
  • TypeScript mais rigoroso: O padrão create<T>()() substitui create<T>()
  • Hidratação persist síncrona: O timing do callback onRehydrateStorage mudou
  • Abandono do suporte CJS: Pacote apenas ESM

Migrar da v4 para a v5 requer atualizar as declarações de importação e ajustar qualquer código que dependia do timing de hidratação anterior.

Pontos-chave para entrevistas sobre Zustand

  • As stores do Zustand vivem fora da árvore React, permitindo acesso síncrono e prevenindo aninhamento de providers
  • Seletores com comparação superficial otimizam re-renders para aplicações em produção
  • O middleware persist requer partialize para excluir funções do armazenamento
  • O padrão slice escala o Zustand para aplicações grandes sem sacrificar a segurança de tipos
  • Ações async funcionam diretamente sem middleware, diferente dos padrões Redux
  • Os testes requerem reset explícito do estado entre casos de teste
  • Server Components forçam o Zustand para boundaries cliente, influenciando decisões de arquitetura

Comece a praticar!

Teste seus conhecimentos com nossos simuladores de entrevista e testes tecnicos.

Desafio do dia

Você saberia encontrar o bug em React / Next.js?

Um trecho real, um bug escondido, uma tentativa por dia. Sem conta para testar.

Anthony Fillion-Maillet

Escrito por

Anthony Fillion-Maillet

Fundador da SharpSkill

Desenvolvedor fullstack há mais de 10 anos. Dirige a SharpSkill e responde por tudo o que é publicado aqui.

Atualizado em 25 de agosto de 2026

Tags

#zustand
#react
#state-management
#interview
#typescript

Compartilhar

Artigos relacionados