// Enforces TheOne Studio React Native development standards including TypeScript patterns, React/Hooks best practices, React Native architecture (Zustand/Jotai, Expo Router), and mobile performance optimization. Triggers when writing, reviewing, or refactoring React Native code, implementing mobile features, working with state management/navigation, or reviewing pull requests.
| name | theone-react-native-standards |
| description | Enforces TheOne Studio React Native development standards including TypeScript patterns, React/Hooks best practices, React Native architecture (Zustand/Jotai, Expo Router), and mobile performance optimization. Triggers when writing, reviewing, or refactoring React Native code, implementing mobile features, working with state management/navigation, or reviewing pull requests. |
โ ๏ธ React Native Latest + TypeScript: All patterns use latest React Native with TypeScript strict mode, Expo SDK 51+, and modern React 18+ patterns.
This skill enforces TheOne Studio's comprehensive React Native development standards with CODE QUALITY FIRST:
Priority 1: Code Quality & Hygiene (MOST IMPORTANT)
Priority 2: Modern React & TypeScript
Priority 3: React Native Architecture
Priority 4: Mobile Performance
| Priority | Task | Reference |
|---|---|---|
| ๐ด PRIORITY 1: Code Quality (Check FIRST) | ||
| 1 | TypeScript strict, ESLint, Prettier, no any types | Quality & Hygiene โญ |
| 1 | Path aliases (@/), structured logging, error handling | Quality & Hygiene โญ |
| 1 | File naming, no inline styles, consistent imports | Quality & Hygiene โญ |
| ๐ก PRIORITY 2: Modern React/TypeScript | ||
| 2 | Functional components, Hooks rules, custom hooks | Modern React |
| 2 | useCallback, useMemo, React.memo optimization | Modern React |
| 2 | Type-safe props, generics, utility types | TypeScript Patterns |
| 2 | Discriminated unions, type guards, inference | TypeScript Patterns |
| ๐ข PRIORITY 3: React Native Architecture | ||
| 3 | Functional components, composition, HOCs | Component Patterns |
| 3 | Zustand patterns, Jotai atoms, persistence | State Management |
| 3 | Expo Router (file-based), React Navigation setup | Navigation |
| 3 | Platform checks, .ios/.android files, Platform module | Platform-Specific |
| ๐ต PRIORITY 4: Performance | ||
| 4 | FlatList optimization, getItemLayout, keyExtractor | Performance |
| 4 | Rerender prevention, React.memo, useMemo | Performance |
| 4 | Architecture violations (components, state, navigation) | Architecture Review |
| 4 | TypeScript quality, hooks violations, ESLint | Quality Review |
| 4 | List optimization, memory leaks, unnecessary rerenders | Performance Review |
ALWAYS enforce these BEFORE writing any code:
Example: Enforce Quality First
// โ
EXCELLENT: All quality rules enforced
// 1. TypeScript strict mode in tsconfig.json
// {
// "compilerOptions": {
// "strict": true,
// "noImplicitAny": true,
// "strictNullChecks": true
// }
// }
// 2. Import order: React โ libraries โ local
import React, { useCallback, useMemo } from 'react'; // React first
import { View, Text, StyleSheet } from 'react-native'; // Libraries
import { useStore } from '@/stores/user-store'; // Local with path alias
// 3. Type-safe props (no any)
interface UserProfileProps {
userId: string;
onPress?: () => void;
}
// 4. Functional component with typed props
export const UserProfile: React.FC<UserProfileProps> = ({ userId, onPress }) => {
const user = useStore((state) => state.users[userId]);
// 5. Throw errors (not console.log)
if (!user) {
throw new Error(`User not found: ${userId}`);
}
// 6. Structured logging
const handlePress = useCallback(() => {
logger.info('User profile pressed', { userId });
onPress?.();
}, [userId, onPress]);
return (
<View style={styles.container}>
<Text style={styles.name}>{user.name}</Text>
</View>
);
};
// 7. No inline styles - use StyleSheet
const styles = StyleSheet.create({
container: {
padding: 16,
},
name: {
fontSize: 18,
fontWeight: 'bold',
},
});
Choose ONE state management solution per project:
Option 1: Zustand (Recommended for Simple State)
Option 2: Jotai (Recommended for Atomic State)
Universal Rules (Both Solutions):
Option 1: Expo Router (Recommended)
Option 2: React Navigation 7
NEVER use ScrollView + map for lists:
// โ BAD: ScrollView + map (terrible performance)
<ScrollView>
{items.map(item => <Item key={item.id} {...item} />)}
</ScrollView>
// โ
GOOD: FlatList with proper optimization
<FlatList
data={items}
renderItem={({ item }) => <Item {...item} />}
keyExtractor={(item) => item.id}
getItemLayout={(data, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
})}
removeClippedSubviews
maxToRenderPerBatch={10}
windowSize={11}
/>
// โ BAD: Class component, inline styles, no types
class UserCard extends React.Component {
render() {
return (
<View style={{ padding: 10 }}>
<Text>{this.props.name}</Text>
</View>
);
}
}
// โ
GOOD: Functional component, typed props, StyleSheet
interface UserCardProps {
name: string;
onPress?: () => void;
}
export const UserCard: React.FC<UserCardProps> = ({ name, onPress }) => {
return (
<View style={styles.container}>
<Text style={styles.name}>{name}</Text>
</View>
);
};
const styles = StyleSheet.create({
container: { padding: 10 },
name: { fontSize: 16 },
});
// โ BAD: useState for app-level state
function App() {
const [user, setUser] = useState(null);
const [settings, setSettings] = useState({});
return <AppContent user={user} settings={settings} />;
}
// โ
GOOD: Zustand for app-level state
import { create } from 'zustand';
interface AppState {
user: User | null;
settings: Settings;
setUser: (user: User | null) => void;
}
export const useAppStore = create<AppState>((set) => ({
user: null,
settings: {},
setUser: (user) => set({ user }),
}));
function App() {
const user = useAppStore((state) => state.user);
return <AppContent />;
}
// โ BAD: ScrollView + map
<ScrollView>
{users.map(user => (
<UserCard key={user.id} user={user} />
))}
</ScrollView>
// โ
GOOD: FlatList with optimization
const ITEM_HEIGHT = 80;
<FlatList
data={users}
renderItem={({ item }) => <UserCard user={item} />}
keyExtractor={(item) => item.id}
getItemLayout={(_, index) => ({
length: ITEM_HEIGHT,
offset: ITEM_HEIGHT * index,
index,
})}
/>
| Mistake | Why It's Wrong | Correct Approach |
|---|---|---|
| Using class components | Outdated, verbose, no hooks | Use functional components |
Using any type | Defeats TypeScript safety | Use proper types or unknown |
| Inline styles in JSX | Poor performance, not reusable | Use StyleSheet.create() |
| ScrollView + map for long lists | Memory issues, poor performance | Use FlatList with optimization |
| Direct console.log | Not structured, no filtering | Use logger utility |
| Mistake | Why It's Wrong | Correct Approach |
|---|---|---|
| Not using path aliases | Ugly relative imports | Configure @/ alias |
| Missing keyExtractor | Poor list performance | Always provide keyExtractor |
| Not memoizing callbacks | Causes unnecessary rerenders | Use useCallback |
| Platform checks in render | Duplicated logic | Use Platform-specific files |
| Not cleaning up effects | Memory leaks | Return cleanup function |
| Pattern | Issue | Optimization |
|---|---|---|
| Expensive calculations in render | Recalculates every render | Use useMemo |
| Props causing child rerenders | Child rerenders unnecessarily | Use React.memo |
| Large lists without optimization | Slow scrolling | Add getItemLayout |
| Deep object comparisons | Expensive checks | Use shallow equality |
| Large bundles | Slow app startup | Code splitting, lazy loading |
Use this checklist when reviewing React Native code:
any types usedRecommended Stack:
Development Tools:
All detailed patterns and examples are in reference files: