UI Standards
This section provides comprehensive guidelines for building user interfaces in Decentraland applications using Redux Toolkit (RTK) and RTK Query. These standards ensure consistent state management, optimal performance, and maintainable code across all UI projects.
Overview
Our UI architecture is built on three core technologies:
- Redux Toolkit (RTK) - Modern Redux with less boilerplate
- RTK Query - Powerful data fetching and caching
- TypeScript - Type-safe state management
Guiding Principles
- Simplicity first - Use RTK Query for remote data;
createSlicefor UI/local state - Feature co-location - Keep related code together (slices, endpoints, selectors)
- Serializable store - Never store non-serializable objects in Redux
- Lean store - Keep ephemeral state in React components
- Strict typing - Leverage TypeScript for better DX and fewer bugs
- Web3-aware - Handle blockchain state changes gracefully
Documentation Sections
- Store Setup - Configure the Redux store, typed hooks, and folder structure
- RTK Query - Data fetching, caching, tags, and invalidation
- State Management - Creating slices and managing UI state
- Component Patterns - Using hooks effectively in components
- Web3 Integration - Patterns for blockchain integration
- Testing & Performance - Best practices, testing, and optimization
Quick Reference: Glossary
Core Concepts
| Term | Description |
|---|---|
| Store | The single Redux state tree for the app |
| Slice | A module created with createSlice (name + initial state + reducers) |
| Action | A plain object describing "what happened" (type + optional payload) |
| Reducer | A pure function that updates state based on actions |
| Selector | A function that reads/derives data from the store (can be memoized) |
RTK Query
| Term | Description |
|---|---|
| RTK Query | Data-fetching layer: endpoints, caching, refetch, invalidations |
| Base Query | The low-level fetcher (e.g., fetchBaseQuery) used by endpoints |
| Endpoint | One RTK Query operation (query = read; mutation = write) |
| Tags | Strings/objects for cache provides/invalidates to sync views |
onQueryStarted |
Lifecycle hook for optimistic updates and rollback |
Patterns
| Term | Description |
|---|---|
| Optimistic update | Temporarily update UI before server confirms; rollback if fails |
| Entity Adapter | Helpers to manage normalized collections (ids/entities, sorting) |
| UI/local state | Client-owned state (filters, modals, form inputs) |
| Remote data | Server-owned/cached data (catalog, NFTs, orders) |
| Typed hooks | useAppSelector/useAppDispatch bound to RootState/AppDispatch |
Why Typed Hooks?
We use useAppSelector and useAppDispatch instead of the standard Redux hooks because:
- Type Safety - Selector return types are checked against
RootState - Less Boilerplate - No
<RootState>generics needed per usage - Easier Refactors - Change store types once; all components follow
- Better DX - Works seamlessly with RTK Query type inference
Getting Started
- Review the Store Setup to understand project structure
- Learn RTK Query for managing remote data
- Understand State Management for local UI state
- Study Component Patterns for implementation
- Follow Web3 Integration for blockchain features
- Apply Testing & Performance best practices
Standards Compliance
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this documentation are to be interpreted as described in RFC 2119.
What's Different About Our Approach
RTK Query First
We prioritize RTK Query for all remote data instead of writing custom async actions. This gives us:
- Built-in caching and deduplication
- Automatic refetching and background updates
- Optimistic updates with rollback
- Loading and error states out of the box
Minimal Store Footprint
We keep the Redux store focused on:
- Remote data cache (via RTK Query)
- Global UI state (filters, preferences, session)
- Cross-component state (modals, notifications)
Transient state stays in React components.
Web3 Considerations
Our patterns account for blockchain-specific challenges:
- Non-serializable objects (providers, signers) stay outside Redux
- Cache invalidation on network/account changes
- Optimistic updates for pending transactions
- Event-driven state updates from blockchain events
Anti-Patterns to Avoid
Never do these:
- Store
window.ethereum, providers, signers, or sockets in Redux - Duplicate the same collection in a slice and in RTK Query
- Dispatch actions during React render
- Return new objects from selectors without memoization
- Create mutations that don't invalidate or patch caches
Next Steps
Start with Store Setup to learn how to structure your project and configure Redux properly.
Related Standards
- Dependency Management - Managing npm dependencies and peerDependencies
- Testing Standards - Testing patterns for UIs and services
- Web UI Standards - Component library and design system