## Busting the Myth: 'JavaScript Alone is Fine for Expo React Native – No Need for TypeScript'
Think TypeScript is just extra typing for web devs? Wrong! In Expo React Native, skipping TypeScript is like driving without a seatbelt. It catches errors at compile time, auto-completes props, and makes your codebase scale effortlessly. Expo's own monorepo is fully TypeScript-powered – check it out [here](https://github.com/expo/expo/tree/main/packages/expo).
**Real-world win:** Imagine refactoring a component tree; TypeScript flags mismatches instantly, saving hours. Start new projects with `npx create-expo-app --template tabs@typescript`. Existing JS? Run `npx expo install typescript @types/react @types/react-native` and rename `.js` to `.tsx`/`ts`. Pro tip: Use `expo-doctor` to spot issues early.
```bash
npx expo install typescript @types/react @types/react-native
```
This shift alone slashes runtime crashes by 40-50% in large apps.
## Myth Busted: 'Inline Styles Are Quick and Harmless'
'Who needs StyleSheet when `style={{color: 'red'}}` works?' Famous last words. Inline styles recalculate on every render, tanking performance, disabling fast refresh, and blocking style caching. StyleSheet.create batches them, enables flattening, and optimizes for native.
**Actionable example:**
```javascript
import { StyleSheet, View, Text } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
},
});
function MyComponent() {
return (
<View style={styles.container}>
<Text style={styles.title}>Hello, Expo!</Text>
</View>
);
}
```
Add value: Pair with `useColorScheme` for dark mode – styles adapt without re-renders. Tools like NativeWind or Tamagui build on this for Tailwind-like utility classes, but start pure for learning.
## The Animation Trap: 'Built-in Animated is Enough'
Myth: React Native's Animated API handles everything smoothly. Reality: It blocks the JS thread, causing jank on low-end devices. Enter Reanimated 3 – worklet magic runs animations on the UI thread for buttery 60fps.
**Pro setup:** `npx expo install react-native-reanimated`. Wrap app in `GestureHandlerRootView`.
```javascript
import Animated, { useSharedValue, useAnimatedStyle, withSpring } from 'react-native-reanimated';
function AnimatedBox() {
const translateX = useSharedValue(0);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: translateX.value }],
}));
return (
<Animated.View style={[styles.box, animatedStyle]} onPress={() => {
translateX.value = withSpring(100);
}} />
);
}
```
**Why it rocks:** Gestures, springs, and shared values make interactions feel native. Use for lists, modals – anywhere motion matters. Bonus: Integrates with expo-router transitions seamlessly.
## Performance Killer: 'No Need to Memoize – React is Smart'
'React handles it!' Nope. Frequent re-renders crush battery and FPS. Bust it with React.memo, useMemo, and useCallback.
- **React.memo** for pure components.
- **useMemo** for expensive computations.
- **useCallback** for event handlers.
**Example showdown:**
```javascript
const ExpensiveListItem = React.memo(({ item }) => (
<View>
<Text>{item.name}</Text>
</View>
));
const data = useMemo(() => heavyCompute(items), [items]);
const onPress = useCallback(() => doSomething(), []);
```
In lists, this prevents 100+ child re-renders. Measure with Flipper or React DevTools Profiler.
## Lists Debacle: 'ScrollView Works for Everything'
Myth: ScrollView + map() is simple. Truth: Virtualized lists are non-negotiable for 100+ items. Order: FlashList > FlatList > ScrollView.
Install `expo install @shopify/flash-list` for the fastest. It leverages native RecyclerListView under the hood.
```javascript
import { FlashList } from '@shopify/flash-list';
<FlashList
data={items}
renderItem={({ item }) => <Item item={item} />}
estimatedItemSize={100}
/>;
```
**Real app tip:** `estimatedItemSize` predicts heights for zero lag scrolling. Gamesaver for feeds, chats.
## Navigation Nonsense: 'Any Router Does the Job'
'Link from react-router?' No. expo-router is file-based, type-safe magic for Expo. URLs as code, zero config deeplinks.
Setup: `npx create-expo-app --template tabs`. Routes in `app/` folder drive it.
**Power move:** Layouts, stacks, tabs – all declarative. Integrates Reanimated transitions out-of-box.
## Data Fetching Fiasco: 'useEffect + fetch is Standard'
Myth: `useEffect(() => { fetch() }, [])` rules. Bust: Race conditions, no caching, infinite loops. Use TanStack Query or SWR.
`npx expo install @tanstack/react-query`
```javascript
import { useQuery } from '@tanstack/react-query';
function UserList() {
const { data, isLoading } = useQuery(['users'], fetchUsers);
if (isLoading) return <Loading />;
return <FlashList data={data} />;
}
```
Cache, refetch on focus, optimistic updates – enterprise-ready.
## Hidden Heroes: Splash, Fonts, Icons
- **Splash:** `expo-splash-screen` prevents white flashes. Hide async in `useEffect`.
- **Fonts:** `expo-font` – preload custom typefaces.
- **Icons:** `expo-vector-icons` or Lucide for modern SVGs.
```javascript
import * as Font from 'expo-font';
useEffect(() => {
Font.loadAsync({ 'Custom': require('./font.ttf') });
}, []);
```
## Optimization Arsenal
- **Hermes:** Default in Expo – JIT/AOT JS engine crushes V8.
- **Images:** `expo-image` over Image for caching, blurhash.
- **Permissions:** Expo modules auto-handle iOS/Android.
- **Dev Builds:** `expo dev-build` for native modules without ejecting.
## Dev Workflow Wins
- EAS Build: CI/CD heaven.
- Flipper: Debug native.
- Prebuild: Customize natives.
**Final myth:** 'Expo limits you.' Nope – full RN power with 90% less hassle. Follow these, ship faster, users happier. Your app, pro-level.
(Word count: ~1150)
<div style="text-align: center; margin-top: 2rem;">
<a href="https://cursor.directory/expo-react-native-javascript-best-practices" target="_blank" rel="noopener noreferrer" class="view-full-resource-btn" style="display: inline-block; background-color: #f97316; color: white; padding: 12px 24px; border-radius: 8px; text-decoration: none; font-weight: 600; transition: background-color 0.2s;">View Full Resource</a>
</div>