Mejores Prácticas y Errores Comunes de Pinia
Mejores prácticas y manejo de errores comunes de Pinia Store en un proyecto de plataforma multi-marca.
1. Ejes principales de respuesta en entrevista
- Principios de diseño: Principio de responsabilidad única, mantener el Store simple, no llamar APIs directamente en el Store.
- Errores comunes: Pérdida de reactividad al desestructurar directamente, llamar al Store fuera de Setup, romper la reactividad al modificar el State, dependencias circulares.
- Mejores prácticas: Usar TypeScript, separación de responsabilidades, combinar múltiples Stores en Composables.
2. Principios de diseño del Store
2.1 Principio de responsabilidad única
// ✅ Buen diseño: Cada Store solo se encarga de un dominio
useAuthStore(); // Solo autenticación
useUserInfoStore(); // Solo información del usuario
useGameStore(); // Solo información del juego
// ❌ Mal diseño: Un Store gestiona todo
useAppStore(); // Gestiona autenticación, usuario, juegos, configuración...
2.2 Mantener el Store simple
// ✅ Recomendado
export const useBannerStore = defineStore('bannerStore', () => {
const bannerState = reactive({ list: [] });
function setStoreBannerList(list: Response.BannerList) {
bannerState.list = list;
}
return { bannerState, setStoreBannerList };
});
// ❌ No recomendado: Store con lógica de negocio compleja
// Debería estar en un composable
2.3 No llamar APIs directamente en el Store
// ❌ No recomendado: Llamada directa a API en el Store
export const useGameStore = defineStore('gameStore', {
actions: {
async fetchGames() {
const data = await api.getGames(); // Llamada API
this.list = data;
},
},
});
// ✅ Recomendado: Llamar API en el Composable, Store solo almacena
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(); // Llamada API en Composable
if (status) {
gameStore.setGameList(data); // Store solo almacena
}
}
return { fetchGames };
}
3. Usar TypeScript
// ✅ Definición 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. Errores comunes
4.1 Error 1: Pérdida de reactividad al desestructurar directamente
// ❌ Incorrecto
const { count } = useCounterStore();
count; // No es reactivo
// ✅ Correcto
const { count } = storeToRefs(useCounterStore());
count.value; // Reactivo
4.2 Error 2: Llamar al Store fuera de Setup
// ❌ Incorrecto: Llamada a nivel de módulo
const authStore = useAuthStore(); // ❌ Momento incorrecto
export function useAuth() {
return {
isLogin: authStore.isLogin,
};
}
// ✅ Correcto: Llamada dentro de la función
export function useAuth() {
const authStore = useAuthStore(); // ✅ Momento correcto
return {
isLogin: authStore.isLogin,
};
}
4.3 Error 3: Romper la reactividad al modificar el State
// ❌ Incorrecto: Asignar directamente un nuevo array
function updateList(newList) {
gameState.list = newList; // Puede perder reactividad
}
// ✅ Correcto: Usar splice o push
function updateList(newList) {
gameState.list.length = 0;
gameState.list.push(...newList);
}
// ✅ También se puede usar asignación con reactive
function updateList(newList) {
Object.assign(gameState, { list: newList });
}
4.4 Error 4: Dependencias circulares
// ❌ Incorrecto: Dependencia mutua 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 ❌ Dependencia circular
});
// ✅ Correcto: Combinar en 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 Error 5: Olvidar return
// ❌ Incorrecto: Olvidó return
export const useGameStore = defineStore('gameStore', () => {
const gameState = reactive({ list: [] });
function updateList(list) {
gameState.list = list;
}
// ❌ Olvidó return, el componente no puede acceder
});
// ✅ Correcto
export const useGameStore = defineStore('gameStore', () => {
const gameState = reactive({ list: [] });
function updateList(list) {
gameState.list = list;
}
return { gameState, updateList }; // ✅ return es obligatorio
});
5. Resumen de puntos clave para entrevista
5.1 Principios de diseño del Store
Posible respuesta:
Al diseñar Pinia Stores, sigo varios principios: 1) Principio de responsabilidad única, cada Store solo se encarga de un dominio; 2) Mantener el Store simple, no incluir lógica de negocio compleja; 3) No llamar APIs directamente en el Store, llamar APIs en Composables, el Store solo almacena; 4) Usar definiciones de tipos completas con TypeScript para mejorar la experiencia de desarrollo.
Puntos clave:
- ✅ Principio de responsabilidad única
- ✅ Store simple
- ✅ Separación de responsabilidades
- ✅ Uso de TypeScript
5.2 Errores comunes y cómo evitarlos
Posible respuesta:
Los errores comunes al usar Pinia incluyen: 1) Pérdida de reactividad al desestructurar directamente, se debe usar
storeToRefs; 2) Llamar al Store fuera de Setup, debe llamarse dentro de la función; 3) Romper la reactividad al modificar el State, usar.length = 0oObject.assign; 4) Dependencias circulares, combinar múltiples Stores en Composables; 5) Olvidar return, los Stores con Composition API deben tener return.
Puntos clave:
- ✅ Mantener la reactividad
- ✅ Momento de llamada correcto
- ✅ Métodos de modificación de estado
- ✅ Evitar dependencias circulares
6. Resumen de entrevista
Posible respuesta:
Al usar Pinia en el proyecto, sigo varias mejores prácticas: 1) El diseño del Store sigue el principio de responsabilidad única y se mantiene simple; 2) No llamar APIs directamente en el Store, sino en Composables; 3) Usar definiciones de tipos completas con TypeScript; 4) Prestar atención a errores comunes como pérdida de reactividad, dependencias circulares, etc. Estas prácticas aseguran la mantenibilidad y escalabilidad del Store.
Puntos clave:
- ✅ Principios de diseño del Store
- ✅ Errores comunes y cómo evitarlos
- ✅ Mejores prácticas
- ✅ Experiencia real en proyectos