Melhores Práticas e Erros Comuns do Pinia
Melhores práticas e tratamento de erros comuns do Pinia Store em um projeto de plataforma multi-marca.
1. Eixos principais de resposta em entrevista
- Princípios de design: Princípio de responsabilidade única, manter o Store enxuto, não chamar APIs diretamente no Store.
- Erros comuns: Perda de reatividade ao desestruturar diretamente, chamar Store fora do Setup, quebra de reatividade ao modificar State, dependências circulares.
- Melhores práticas: Usar TypeScript, separação de responsabilidades, combinar múltiplos Stores em Composables.
2. Princípios de design do Store
2.1 Princípio de responsabilidade única
// ✅ Bom design: Cada Store é responsável por apenas um domínio
useAuthStore(); // Apenas autenticação
useUserInfoStore(); // Apenas informações do usuário
useGameStore(); // Apenas informações do jogo
// ❌ Design ruim: Um Store gerencia tudo
useAppStore(); // Gerencia autenticação, usuário, jogos, configurações...
2.2 Manter o Store enxuto
// ✅ Recomendado
export const useBannerStore = defineStore('bannerStore', () => {
const bannerState = reactive({ list: [] });
function setStoreBannerList(list: Response.BannerList) {
bannerState.list = list;
}
return { bannerState, setStoreBannerList };
});
// ❌ Não recomendado: Store com lógica de negócio complexa
// Deveria estar em um composable
2.3 Não chamar APIs diretamente no Store
// ❌ Não recomendado: Chamada direta de API no Store
export const useGameStore = defineStore('gameStore', {
actions: {
async fetchGames() {
const data = await api.getGames(); // Chamada API
this.list = data;
},
},
});
// ✅ Recomendado: Chamar API no Composable, Store apenas armazena
export const useGameStore = defineStore('gameStore', {
actions: {
setGameList(list: Game[]) {
this.list = list;
},
},
});
export function useGame() {
const gameStore = useGameStore();
async function fetchGames() {
const { status, data } = await api.getGames(); // Chamada API no Composable
if (status) {
gameStore.setGameList(data); // Store apenas armazena
}
}
return { fetchGames };
}
3. Usar TypeScript
// ✅ Definição de tipos completa
type UserState = {
info: Response.UserInfo;
walletList: Response.UserWalletList;
};
export const useUserInfoStore = defineStore('useInfoStore', () => {
const state = reactive<UserState>({
info: {} as Response.UserInfo,
walletList: [],
});
return { state };
});
4. Erros comuns
4.1 Erro 1: Perda de reatividade ao desestruturar diretamente
// ❌ Incorreto
const { count } = useCounterStore();
count; // Não é reativo
// ✅ Correto
const { count } = storeToRefs(useCounterStore());
count.value; // Reativo
4.2 Erro 2: Chamar Store fora do Setup
// ❌ Incorreto: Chamada no nível do módulo
const authStore = useAuthStore(); // ❌ Momento incorreto
export function useAuth() {
return {
isLogin: authStore.isLogin,
};
}
// ✅ Correto: Chamada dentro da função
export function useAuth() {
const authStore = useAuthStore(); // ✅ Momento correto
return {
isLogin: authStore.isLogin,
};
}
4.3 Erro 3: Quebra de reatividade ao modificar State
// ❌ Incorreto: Atribuir diretamente um novo array
function updateList(newList) {
gameState.list = newList; // Pode perder reatividade
}
// ✅ Correto: Usar splice ou push
function updateList(newList) {
gameState.list.length = 0;
gameState.list.push(...newList);
}
// ✅ Também possível: Atribuição com reactive
function updateList(newList) {
Object.assign(gameState, { list: newList });
}
4.4 Erro 4: Dependências circulares
// ❌ Incorreto: Dependência mútua entre Stores
// authStore.ts
import { useUserInfoStore } from './userInfoStore';
export const useAuthStore = defineStore('authStore', () => {
const userInfoStore = useUserInfoStore(); // Depende de userInfoStore
});
// userInfoStore.ts
import { useAuthStore } from './authStore';
export const useUserInfoStore = defineStore('useInfoStore', () => {
const authStore = useAuthStore(); // Depende de authStore ❌ Dependência circular
});
// ✅ Correto: Combinar no Composable
export function useInit() {
const authStore = useAuthStore();
const userInfoStore = useUserInfoStore();
async function initialize() {
await authStore.checkAuth();
if (authStore.isLogin) {
await userInfoStore.getUserInfo();
}
}
return { initialize };
}
4.5 Erro 5: Esquecer o return
// ❌ Incorreto: Esqueceu o return
export const useGameStore = defineStore('gameStore', () => {
const gameState = reactive({ list: [] });
function updateList(list) {
gameState.list = list;
}
// ❌ Esqueceu o return, componente não consegue acessar
});
// ✅ Correto
export const useGameStore = defineStore('gameStore', () => {
const gameState = reactive({ list: [] });
function updateList(list) {
gameState.list = list;
}
return { gameState, updateList }; // ✅ return é obrigatório
});
5. Resumo dos pontos-chave para entrevista
5.1 Princípios de design do Store
Possível resposta:
Ao projetar Pinia Stores, sigo vários princípios: 1) Princípio de responsabilidade única, cada Store é responsável por apenas um domínio; 2) Manter o Store enxuto, não incluir lógica de negócio complexa; 3) Não chamar APIs diretamente no Store, chamar APIs nos Composables, o Store apenas armazena; 4) Usar definições de tipos completas com TypeScript para melhorar a experiência de desenvolvimento.
Pontos-chave:
- ✅ Princípio de responsabilidade única
- ✅ Store enxuto
- ✅ Separação de responsabilidades
- ✅ Uso de TypeScript
5.2 Erros comuns e como evitá-los
Possível resposta:
Os erros comuns ao usar Pinia incluem: 1) Perda de reatividade ao desestruturar diretamente, é necessário usar
storeToRefs; 2) Chamar Store fora do Setup, deve ser chamado dentro da função; 3) Quebra de reatividade ao modificar State, usar.length = 0ouObject.assign; 4) Dependências circulares, combinar múltiplos Stores em Composables; 5) Esquecer o return, Stores com Composition API devem ter return.
Pontos-chave:
- ✅ Manter a reatividade
- ✅ Momento correto de chamada
- ✅ Métodos de modificação de estado
- ✅ Evitar dependências circulares
6. Resumo da entrevista
Possível resposta:
Ao usar Pinia no projeto, sigo várias melhores práticas: 1) O design do Store segue o princípio de responsabilidade única e se mantém enxuto; 2) Não chamar APIs diretamente no Store, mas nos Composables; 3) Usar definições de tipos completas com TypeScript; 4) Prestar atenção a erros comuns como perda de reatividade, dependências circulares, etc. Essas práticas garantem a manutenibilidade e escalabilidade do Store.
Pontos-chave:
- ✅ Princípios de design do Store
- ✅ Erros comuns e como evitá-los
- ✅ Melhores práticas
- ✅ Experiência real em projetos