乐闻世界logo
搜索文章和话题

In real projects, how to organize and manage React Query queries, and what are the best practices for project structure and naming conventions?

3月5日 23:34

In real projects, properly organizing and managing React Query queries is crucial for code maintainability and scalability:

Project Structure Organization

  1. Separate Query Functions

    • Separate data fetching logic from components
    • Create dedicated API or service layer
    • Example structure:
      shell
      src/ ├── api/ │ ├── index.js │ ├── users.js │ └── posts.js ├── components/ └── pages/
  2. Custom Hook Encapsulation

    • Create custom hooks to encapsulate common query logic
    • Provide unified interfaces and configurations
    • Example:
      javascript
      // src/hooks/useUsers.js import { useQuery } from 'react-query'; import { fetchUsers } from '../api/users'; export const useUsers = (options = {}) => { return useQuery('users', fetchUsers, { staleTime: 5 * 60 * 1000, ...options, }); };
  3. Query Key Management

    • Create centralized query key constants or utility functions
    • Ensure consistency and maintainability of query keys
    • Example:
      javascript
      // src/utils/queryKeys.js export const queryKeys = { users: 'users', user: (id) => ['user', id], posts: 'posts', userPosts: (userId) => ['posts', 'user', userId], };

Naming Conventions

  1. Query Key Naming

    • Use descriptive names
    • For dynamic parameters, use array format
    • Follow consistent naming patterns (e.g., [resource, id, action])
  2. Custom Hook Naming

    • Use use prefix
    • Names should reflect the purpose of the query
    • Examples: useUsers, useUserPosts, useCreateUser
  3. API Function Naming

    • Use clear verb+noun structure
    • Examples: fetchUsers, createUser, updatePost

Best Practices

  1. Global Configuration

    • Configure QueryClient at application entry
    • Set reasonable default options
    • Example:
      javascript
      // src/App.js import { QueryClient, QueryClientProvider } from 'react-query'; const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 30000, cacheTime: 60000, retry: 2, }, }, }); function App() { return ( <QueryClientProvider client={queryClient}> {/* Application components */} </QueryClientProvider> ); }
  2. Query Grouping and Hierarchy

    • Use hierarchical query keys
    • Facilitate batch operations and invalidation
    • Example:
      javascript
      // Hierarchical query keys const userQueryKey = ['users', userId]; const userPostsQueryKey = ['users', userId, 'posts']; // Batch invalidation queryClient.invalidateQueries(['users', userId]);
  3. Code Splitting and Lazy Loading

    • For large applications, consider code splitting
    • Load query logic on demand
  4. Testing Strategy

    • Mock QueryClient and query responses
    • Test component behavior in different query states
    • Example:
      javascript
      // Using React Testing Library import { render, screen } from '@testing-library/react'; import { QueryClient, QueryClientProvider, useQuery } from 'react-query'; test('renders data when query succeeds', async () => { const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: Infinity, }, }, }); // Pre-populate cache queryClient.setQueryData('todos', [{ id: 1, title: 'Test Todo' }]); render( <QueryClientProvider client={queryClient}> <TodoList /> </QueryClientProvider> ); expect(await screen.findByText('Test Todo')).toBeInTheDocument(); });
  5. Documentation and Comments

    • Add comments for complex queries
    • Document query purposes, cache strategies, and dependencies

By following these best practices, you can create a more structured, maintainable, and scalable React Query codebase, improving development efficiency and code quality.

标签:React