Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Inicio Rápido con TypeScript en Redux Toolkit
- Cómo configurar y usar Redux Toolkit y React-Redux con TypeScript
- Conocimiento de los Hooks de React
- Comprensión de términos y conceptos de Redux
- Comprensión de la sintaxis y conceptos de TypeScript
Introducción
¡Bienvenido al tutorial de inicio rápido de Redux Toolkit con TypeScript! Este tutorial mostrará brevemente cómo usar TypeScript con Redux Toolkit y React-Redux.
Esta página se centra únicamente en cómo configurar los aspectos de TypeScript. Para explicaciones sobre qué es Redux, cómo funciona y ejemplos completos de cómo usar Redux Toolkit, consulta los tutoriales enlazados en la página "Índice de Tutoriales".
Redux Toolkit ya está escrito en TypeScript, por lo que sus definiciones de tipos TS están integradas.
React Redux también está escrito en TypeScript a partir de la versión 8 e incluye sus propias definiciones de tipos.
La plantilla Redux+TS para Create-React-App incluye un ejemplo funcional de estos patrones ya configurado.
Configuración del Proyecto
Definir Tipos de Estado Raíz y Dispatch
La API configureStore de Redux Toolkit no debería requerir tipados adicionales. Sin embargo, convendrá extraer los tipos RootState y Dispatch para poder referenciarlos cuando sea necesario. Inferir estos tipos directamente desde el store garantiza que se actualicen correctamente al añadir más slices de estado o modificar la configuración de middleware.
Dado que son tipos, es seguro exportarlos directamente desde tu archivo de configuración del store (como app/store.ts) e importarlos en otros archivos.
import { configureStore } from '@reduxjs/toolkit'
// ...
export const store = configureStore({
reducer: {
posts: postsReducer,
comments: commentsReducer,
users: usersReducer
}
})
// Infer the `RootState`, `AppDispatch`, and `AppStore` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch
export type AppStore = typeof store
Definir Hooks Tipados
Aunque es posible importar los tipos RootState y AppDispatch en cada componente, es mejor crear versiones tipadas de los hooks useDispatch y useSelector para usar en tu aplicación. Esto es importante por varias razones:
-
Para
useSelector, evita tener que escribir(state: RootState)cada vez -
Para
useDispatch, el tipoDispatchpredeterminado no reconoce los thunks. Para enviar thunks correctamente, necesitas usar el tipo personalizadoAppDispatchdel store que incluye los tipos de middleware thunk, y usarlo conuseDispatch. Añadir un hookuseDispatchpre-tipado evita que olvides importarAppDispatchdonde se necesite.
Dado que son variables reales y no tipos, es importante definirlas en un archivo separado como app/hooks.ts, no en el archivo de configuración del store. Esto permite importarlas en cualquier componente que necesite usar los hooks y evita posibles problemas de dependencias circulares en las importaciones.
import { useDispatch, useSelector } from 'react-redux'
import type { AppDispatch, RootState } from './store'
// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
export const useAppSelector = useSelector.withTypes<RootState>()
Uso en la Aplicación
Definir Tipos de Estado y Acciones del Slice
Cada archivo de slice debe definir un tipo para su estado inicial, para que createSlice pueda inferir correctamente el tipo de state en cada reducer case.
Todas las acciones generadas deben definirse usando el tipo PayloadAction<T> de Redux Toolkit, que toma como argumento genérico el tipo del campo action.payload.
Puedes importar con seguridad el tipo RootState desde el archivo del store aquí. Es una importación circular, pero el compilador de TypeScript puede manejarlo correctamente para tipos. Esto puede ser necesario para casos de uso como escribir funciones selectoras.
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import type { RootState } from '../../app/store'
// Define a type for the slice state
export interface CounterState {
value: number
}
// Define the initial state using that type
const initialState: CounterState = {
value: 0
}
export const counterSlice = createSlice({
name: 'counter',
// `createSlice` will infer the state type from the `initialState` argument
initialState,
reducers: {
increment: state => {
state.value += 1
},
decrement: state => {
state.value -= 1
},
// Use the PayloadAction type to declare the contents of `action.payload`
incrementByAmount: (state, action: PayloadAction<number>) => {
state.value += action.payload
}
}
})
export const { increment, decrement, incrementByAmount } = counterSlice.actions
// Other code such as selectors can use the imported `RootState` type
export const selectCount = (state: RootState) => state.counter.value
export default counterSlice.reducer
Los creadores de acciones generados estarán correctamente tipados para aceptar un argumento payload basado en el tipo PayloadAction<T> que proporcionaste para el reducer. Por ejemplo, incrementByAmount requiere un number como argumento.
En algunos casos, TypeScript puede restringir innecesariamente el tipo del estado inicial. Si esto ocurre, puedes solucionarlo haciendo una conversión de tipo del estado inicial usando as, en lugar de declarar el tipo de la variable:
// Workaround: cast state instead of declaring variable type
const initialState = {
value: 0
} as CounterState
Usar hooks tipados en componentes
En los archivos de componentes, importa los hooks previamente tipados en lugar de los hooks estándar de React-Redux.
import React from 'react'
import { useAppSelector, useAppDispatch } from 'app/hooks'
import { decrement, increment } from './counterSlice'
export function Counter() {
// The `state` arg is correctly typed as `RootState` already
const count = useAppSelector(state => state.counter.value)
const dispatch = useAppDispatch()
// omit rendering logic
}
Ejemplo completo de la aplicación de contador
Aquí tienes la aplicación de contador completa en TypeScript como un CodeSandbox en funcionamiento:
¿Qué sigue?
Recomendamos seguir el tutorial completo "Redux Essentials", que cubre todas las piezas clave incluidas en Redux Toolkit, qué problemas resuelven y cómo usarlas para construir aplicaciones del mundo real.
También puedes leer el tutorial "Redux Fundamentals", que te dará una comprensión completa de cómo funciona Redux, qué hace Redux Toolkit y cómo usarlo correctamente.
Finalmente, consulta la página "Uso con TypeScript" para obtener detalles extensos sobre cómo usar las APIs de Redux Toolkit con TypeScript.