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 stateFeature 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
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
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
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
RootStateLess Boilerplate - No
<RootState>generics needed per usageEasier 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 ReduxDuplicate 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.
Last updated