Overview of Server State Management with TanStack Query
The UTA implementation uses TanStack Query to manage server state, providing a set of practical patterns for fetching, caching, and synchronizing data between the client and server.
website·Indexed 30 days ago
https://dev.updatetheapp.com/docsStandardized React Native development patterns and deployment solutions. The ecosystem features a modular, domain-driven architecture using a Feature-Domain Hybrid organizational strategy, TypeScript, TanStack Query for server state, and Zustand for client state management.
// ui/foundation/Button/Button.tsx
import React from 'react';
import { TouchableOpacity, Text, ActivityIndicator } from 'react-native';
import { styles } from './styles';
import type { ButtonProps } from './types';
export const Button: React.FC<ButtonProps> = ({
title,
onPress,
variant = 'primary',
size = 'medium',
disabled = false,
loading = false,
testID,
...rest
}) => {
const isDisabled = disabled || loading;
return (
<TouchableOpacity
style={[
styles.button,
styles[variant],
styles[size],
isDisabled && styles.disabled,
]}
onPress={onPress}
disabled={isDisabled}
testID={testID}
{...rest}
>
{loading ? (
<ActivityIndicator color={styles[variant].color} />
) : (
<Text style={[styles.text, styles[`${variant}Text`]]}>{title}</Text>
)}
</TouchableOpacity>
);
};Follow the application's Golden Rule: "Component state belongs in React's built-in hooks, not in Zustand or TanStack Query". Use component state for:
Follow these rules to maintain the architecture's integrity:
public/protected object pattern within domain API classes.skipAuth flags to toggle authentication on a single client.public object and others as top-level class methods.Coding standards act as efficiency multipliers by providing the following benefits:
AuthStrategy interface. This allows different clients to use different authentication methods (e.g., Bearer Tokens, API Keys, or OAuth2) while maintaining a consistent client interface.// core/shared/api/auth-strategies.ts
export interface AuthStrategy {
applyAuth(config: AxiosRequestConfig): Promise<AxiosRequestConfig>;
handleAuthError(error: AxiosError): Promise<any>;
}
export class BearerTokenStrategy implements AuthStrategy {
async applyAuth(config: AxiosRequestConfig) {
const token = await tokenService.getAccessToken();
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
}
}
export class ApiKeyStrategy implements AuthStrategy {
constructor(private apiKey: string) {}
async applyAuth(config: AxiosRequestConfig) {
config.headers['X-API-Key'] = this.apiKey;
return config;
}
}
// core/shared/api/clients.ts
export const mainApi = {
public: new PublicApiClient({ baseURL: process.env.MAIN_API_URL }),
authenticated: new AuthenticatedApiClient(
{ baseURL: process.env.MAIN_API_URL },
new BearerTokenStrategy(tokenService)
),
};
export const paymentApi = new AuthenticatedApiClient(
{ baseURL: process.env.PAYMENT_API_URL },
new ApiKeyStrategy(process.env.PAYMENT_API_KEY)
);