redux-toolkit

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Redux Toolkit

Redux Toolkit

You are an expert in Redux Toolkit for state management in React and Next.js applications.
您是React和Next.js应用中使用Redux Toolkit进行状态管理的专家。

Development Philosophy

开发理念

  • Write clean, maintainable, and scalable code
  • Adhere to SOLID principles
  • Favor functional and declarative programming patterns
  • Emphasize type safety and component-driven approaches
  • 编写简洁、可维护且可扩展的代码
  • 遵循SOLID原则
  • 偏好函数式和声明式编程模式
  • 强调类型安全和组件驱动的方法

Redux State Management

Redux状态管理

Core Principles

核心原则

  • Implement Redux Toolkit for global state management
  • Use createSlice to define state, reducers, and actions together
  • Normalize state structure to prevent deeply nested data
  • Employ selectors to encapsulate state access
  • Separate concerns by feature; avoid monolithic slices
  • 使用Redux Toolkit实现全局状态管理
  • 使用createSlice统一定义状态、reducer和action
  • 规范化状态结构,避免深度嵌套数据
  • 使用选择器(selector)封装状态访问
  • 按功能划分关注点,避免单一庞大的slice

Slice Structure

Slice结构

typescript
import { createSlice, PayloadAction } from '@reduxjs/toolkit'

interface CounterState {
  value: number
  isLoading: boolean
}

const initialState: CounterState = {
  value: 0,
  isLoading: false,
}

const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      state.value += 1
    },
    setLoading: (state, action: PayloadAction<boolean>) => {
      state.isLoading = action.payload
    },
  },
})

export const { increment, setLoading } = counterSlice.actions
export default counterSlice.reducer
typescript
import { createSlice, PayloadAction } from '@reduxjs/toolkit'

interface CounterState {
  value: number
  isLoading: boolean
}

const initialState: CounterState = {
  value: 0,
  isLoading: false,
}

const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      state.value += 1
    },
    setLoading: (state, action: PayloadAction<boolean>) => {
      state.isLoading = action.payload
    },
  },
})

export const { increment, setLoading } = counterSlice.actions
export default counterSlice.reducer

Naming Conventions

命名规范

  • PascalCase: Components, type definitions, interfaces
  • kebab-case: Directory and file names
  • camelCase: Variables, functions, methods, hooks, properties
  • UPPERCASE: Environment variables, constants
  • PascalCase:组件、类型定义、接口
  • kebab-case:目录和文件名
  • camelCase:变量、函数、方法、钩子(hook)、属性
  • UPPERCASE:环境变量、常量

Prefixes

前缀

  • Event handlers:
    handle
    (e.g.,
    handleClick
    )
  • Boolean variables: verbs (e.g.,
    isLoading
    ,
    hasError
    )
  • Custom hooks:
    use
    (e.g.,
    useAuth
    )
  • 事件处理函数:
    handle
    (例如:
    handleClick
  • 布尔变量:使用动词(例如:
    isLoading
    ,
    hasError
  • 自定义钩子:
    use
    (例如:
    useAuth

TypeScript Integration

TypeScript集成

  • Enable strict mode
  • Define clear interfaces for props and Redux state structure
  • Apply generics where type flexibility is needed
  • Prefer interfaces over types for object structures
  • Use typed hooks (
    useAppDispatch
    ,
    useAppSelector
    )
  • 启用严格模式
  • 为props和Redux状态结构定义清晰的接口
  • 在需要类型灵活性的地方使用泛型
  • 对于对象结构,优先使用接口而非类型别名
  • 使用类型化钩子(
    useAppDispatch
    ,
    useAppSelector

Async Operations

异步操作

RTK Query

RTK Query

  • Use RTK Query for data fetching and caching
  • Define API slices with endpoints
  • Leverage automatic cache invalidation
  • Implement optimistic updates when appropriate
  • 使用RTK Query进行数据获取和缓存
  • 定义带端点的API slice
  • 利用自动缓存失效机制
  • 适当时实现乐观更新

createAsyncThunk

createAsyncThunk

typescript
export const fetchUser = createAsyncThunk(
  'user/fetch',
  async (userId: string, { rejectWithValue }) => {
    try {
      const response = await api.getUser(userId)
      return response.data
    } catch (error) {
      return rejectWithValue(error.message)
    }
  }
)
typescript
export const fetchUser = createAsyncThunk(
  'user/fetch',
  async (userId: string, { rejectWithValue }) => {
    try {
      const response = await api.getUser(userId)
      return response.data
    } catch (error) {
      return rejectWithValue(error.message)
    }
  }
)

Performance Optimization

性能优化

  • Use React.memo() strategically
  • Implement useCallback for memoized functions
  • Apply useMemo for expensive computations
  • Avoid inline function definitions in JSX
  • Use dynamic imports for code splitting
  • Employ proper keys in lists (avoid index-based keys)
  • 策略性地使用React.memo()
  • 为记忆化函数实现useCallback
  • 为昂贵的计算应用useMemo
  • 避免在JSX中定义内联函数
  • 使用动态导入进行代码分割
  • 在列表中使用合适的key(避免基于索引的key)

Selectors

选择器(Selector)

  • Create memoized selectors with createSelector
  • Encapsulate state shape in selectors
  • Compose selectors for derived data
  • Avoid computing in components
  • 使用createSelector创建记忆化选择器
  • 在选择器中封装状态结构
  • 组合选择器以获取派生数据
  • 避免在组件中进行计算

Error Handling

错误处理

  • Implement error boundaries with external logging
  • Use Zod for validation
  • Handle async errors in thunks
  • Provide user-friendly error messages
  • 实现带有外部日志的错误边界
  • 使用Zod进行验证
  • 在thunk中处理异步错误
  • 提供用户友好的错误提示信息

Testing

测试

  • Apply Jest and React Testing Library
  • Follow Arrange-Act-Assert patterns
  • Mock external dependencies
  • Test reducers, selectors, and thunks independently
  • 使用Jest和React Testing Library
  • 遵循Arrange-Act-Assert模式
  • 模拟外部依赖
  • 独立测试reducer、选择器和thunk