Busca en todas las páginas de la documentación
251 pages across 49 sections. 1910 questions total.
react-native core or Expo modules that ship with the default template.expo-asset assume an Expo or prebuild workflow, but the underlying rules hold in bare RN too.<Text>, even single words inside a View.memo and force every visible row to re-render on each parent tick.useCallback and keep row components memoized.Platform.select inside a shared file is cleaner.newArchEnabled in app.json / app.config.js (enabled by default in recent templates).npx expo-doctor and inspect native build logs for Fabric/TurboModule initialization.Dimensions.get('window') call in component render with useWindowDimensions().@3x asset at thousands of pixels wide and displaying it in a 48×48 avatar.expo-image with appropriate resize modes.UILabel / TextView instances.View is a layout container only; it cannot render glyphs.column - children stack vertically top-to-bottom.flexDirection: "row" explicitly for horizontal toolbars and chip rows.<Text style={styles.body}>
Already have an account?{" "}
<Text style={styles.link} onPress={goToLogin}>
Sign in
</Text>
</Text>Text inherits parent font size and color unless overridden.ScrollView renders all children at once - fine for short content.FlatList virtualizes rows - required for long feeds to avoid memory and layout cost.ScrollView is simpler and predictable.shadowColor, shadowOffset, shadowOpacity, shadowRadius.elevation on the view background.Platform.select inside StyleSheet.create.style applies to the scroll viewport (the visible window).contentContainerStyle applies to the inner wrapper that moves when scrolling.gap, and flexGrow: 1 on contentContainerStyle, not style.SafeAreaView from react-native-safe-area-context (included in Expo templates).edges={["top", "left", "right"]} to avoid double bottom padding above tab bars.Text accepts onPress, onLongPress, and pressRetentionOffset.Pressable with a Text child for clearer roles and larger hit targets.Text press use case.gap, rowGap, and columnGap are supported in React Native 0.71+.View and ScrollView contentContainerStyle.numberOfLines needs a bounded width to measure overflow.flex: 1, a fixed width, or flexShrink: 1 on the Text or parent row.StyleSheet.create validates keys, enables reuse, and reads cleaner in diffs.{ opacity: pressed ? 0.6 : 1 }).style={[styles.base, { backgroundColor: color }]}.Text nesting, style shapes) are unchanged from the developer perspective.<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Centered</Text>
</View>justifyContent aligns on the main axis (column = vertical).alignItems aligns on the cross axis (column = horizontal).width: "100%" and height: "50%" resolve against the parent.useWindowDimensions in the dimensions article.pointerEvents="none" lets touches pass through to views below - useful for decorative overlays.box-none ignores touches on the container but allows children to receive them.auto; change only when debugging overlapping touch targets.memo).setTimeout, fetch resolutions, and native events batch by default.setState calls in the same tick produce one re-render.flushSync only when you intentionally need a synchronous paint (rare on mobile).renderItem unless memoized; new function identity can defeat row memoization.memo on the row, stable useCallback handlers, and extraData only when needed.setState / useReducer.style={{ flex: 1 }} creates a new object every time.useCallback and hoist styles to StyleSheet.create.useRef stores mutable values that should not trigger re-renders when updated.useState.FlatList is a PureComponent - it may skip renderItem if data reference is unchanged.extraData={selectedId} when row appearance depends on state outside data.// Wrong - each call uses the same snapshot
setCount(count + 1);
setCount(count + 1);
// Right - functional updater chains on latest value
setCount((c) => c + 1);
setCount((c) => c + 1);count variable in the closure is stale within the same handler.memo bails out with same props.children prop identity changes if the parent inline-defines JSX that captures new closures.expo-router and React Navigation pass route params as props or hook values (useLocalSearchParams).useEffect, not in the render body.setTodos((prev) => ...) so you do not close over todos.id arguments rather than capturing loop variables when possible.useMemo only caches a computed value between renders of the same component.memo on children when passing memoized objects or arrays down.Pressable exposes pressed, hovered, and focused states in a style function.android_ripple, hitSlop, and accessibility props are first-class.TouchableOpacity always animates opacity - less control and wider re-render surface on big trees.ScrollView before release.disabled={true} is set on the Pressable.<Pressable
android_ripple={{ color: "rgba(0,0,0,0.12)" }}
style={({ pressed }) => [styles.btn, pressed && styles.btnPressed]}
/>android_ripple is ignored on iOS - safe to ship in cross-platform files.pressed style (typically lower opacity or background change).delayPressIn (default 0) can be raised by parents or ScrollView press retention.onPressIn blocks the next frame.onPress or requestAnimationFrame; show highlight immediately.onLongPress fires (default 500).onPress still fires on quick taps unless long-press handler consumes the gesture.auto (default) - view and children receive touches.none - view and children are transparent to touches.box-none - view ignores touches; children still receive them.box-only - view receives touches; children do not.Pressable for new code - clearer state and ripple control.TouchableHighlight underlay can flash incorrectly in virtualized lists during fast scroll.onPress closures per item.const [submitting, setSubmitting] = useState(false);
const onSubmit = async () => {
if (submitting) return;
setSubmitting(true);
try {
await save();
} finally {
setSubmitting(false);
}
};
<Pressable onPress={onSubmit} disabled={submitting} />Pressable row with child Text nodes.accessibilityRole="button" marks the element for screen readers.accessibilityLabel when visible text is insufficient (icon-only).accessibilityState={{ disabled, selected, busy }} mirrors visual state.accessibilityHint for destructive or non-obvious outcomes.GestureDetector for advanced cases.Pressable callbacks execute on the JavaScript thread (Hermes).react-native-reanimated can stay on the UI thread separately.TextInput, keyboardShouldPersistTaps="handled" lets taps on Pressable fire without dismissing the keyboard first.hitSlop - both solve different problems.hitSlop.Pressable props; tune when users report "slip off" cancellations."ios" and "android"."web", and RN supports "macos" and "windows" in some templates.Platform.OS === "ios" rather than assuming only two platforms.Foo.ios.tsx first, then Foo.native.tsx, then Foo.tsx.Foo.android.tsx replaces the .ios step.Platform.select for style values, numeric constants, and small config objects.*.web.tsx implementation..ios) beats .native beats generic .tsx.default key, unmatched platforms receive undefined.default or an explicit web key.Platform.select({...}) ?? fallback.app/ but components can split normally..ios unless you intend OS-specific screens.const spacing = Platform.select({
ios: 8,
android: 12,
default: 10,
}); // number | undefined without default - use default key"18.0") - parse to integer major version for comparisons.34) - compare numerically.{Platform.OS === "ios" && <BlurView />}) are fine.*.web.tsx when present..web, web may fall back to .tsx or .native.tsx depending on resolver config.*.web.tsx when mobile code imports native-only modules../Button always - let the bundler pick the right file.Component.types.ts with props interfaces.Component.ios.tsx / Component.android.tsx imports the same types.Component.tsx barrel that re-exports the resolved implementation.Platform.OS via jest.spyOn(Platform, "OS", "get").Platform.OS is "web".ios - set explicitly per suite.expo-constants exposes executionEnvironment, sessionId, platform subtleties, and EAS metadata.Platform for quick OS branches in UI components..ios.ts / .android.ts stubs with matching TypeScript signatures.index.ts so app code stays platform-agnostic.Metro's bundler scans your source at build time and includes only assets it can resolve statically. Dynamic path construction cannot be analyzed, so the bundler throws an error. Use a constant map:
const icons = {
home: require("./assets/home.png"),
settings: require("./assets/settings.png"),
} as const;Name files with @2x and @3x suffixes alongside the base file. Metro selects the best match for the device's PixelRatio at runtime. You always require() the base filename - never the suffixed variant directly.
Yes. React Native does not infer layout size from image metadata for either local or remote sources. Set width/height in StyleSheet or use aspectRatio with one dimension.
defaultSource (iOS-focused; limited Android support) shows a bundled image while the remote { uri } loads. For cross-platform placeholder UX, prefer expo-image with placeholder / blurhash props or render a skeleton View until onLoad fires.
import { Image } from "react-native";
import { Asset } from "expo-asset";
// Core Image prefetch (remote only)
await Image.prefetch("https://cdn.example.com/hero.jpg");
// expo-asset (local require IDs and remote URLs)
await Asset.loadAsync([require("./assets/card-bg.png")]);Yes. iOS and Android in current Expo SDK builds decode WebP. WebP often yields smaller bundles than PNG for photos and illustrations. Keep PNG for images requiring lossless transparency at small sizes.
Unstable source={{ uri }} object references can trigger re-fetches. Memoize the source object or pass a stable URI string via expo-image's source prop. Avoid cache-busting query params unless intentional.
Use expo-font's useFonts or Font.loadAsync in the same bootstrap routine as Asset.loadAsync. Both should complete before you hide the splash screen and render text-heavy UI.
cover fills the frame and crops - good for uniform avatar circles. contain fits the entire image inside the frame - good for logos with varied aspect ratios where cropping is unacceptable.
const [error, setError] = useState(false);
<Image
source={error ? require("./assets/fallback.png") : { uri }}
onError={() => setError(true)}
style={{ width: 48, height: 48 }}
/>Expo projects conventionally use a top-level assets/ folder for app icons and splash images (referenced in app.json), and co-located ./assets/ folders next to screens for feature-specific images. Both work - consistency within a feature matters more than the exact folder name.
It registers assets in Expo's asset system, downloads remote URLs to a cache directory when needed, and ensures native resources are available before your JS references them. For bundled require() assets, it primarily guarantees preload completion via promises.
Decorative images should set accessible={false} so screen readers skip them. Meaningful images (avatars, charts) need accessibilityLabel describing the content. Purely decorative bundled icons usually need no label.
React Native does not serve a public/ folder like the web. All bundled images must be imported with require() (or preloaded via expo-asset). Remote images use HTTPS URLs.
Dimensions.get() returns a snapshot at call time. It does not re-render your component when the user rotates the device or resizes split-screen. useWindowDimensions is a hook that subscribes to dimension changes and triggers a re-render automatically.
window - the usable app viewport (what most layouts need).screen - the full physical display, including areas under status/navigation bars on some Android devices.Default to window unless you have a specific fullscreen use case.
768 is the most common convention (iPad portrait is 768 dp). Some teams use 600 (Material "tablet" threshold) or 1024 for desktop-class layouts. Pick one, document it, and use it consistently.
import { PixelRatio } from "react-native";
const physicalPixels = layoutDp * PixelRatio.get();A 100×100 dp box is 200×200 physical pixels on a 2x device and 300×300 on a 3x device.
On tablet (width >= 768), render list and detail in a flexDirection: 'row' container. On phone, use Expo Router / React Navigation stack - list screen pushes detail screen. Pass the same data layer to both layouts.
Yes. It is a standard React Native hook. Use it inside any client component screen or layout. It updates when the router-mounted screen rotates or resizes.
Split-screen shrinks window.width dramatically. A tablet-width breakpoint may not fire even on a large device. Test narrow widths and prefer flex-based layouts that degrade gracefully.
Use expo-screen-orientation to lock or unlock orientation per screen. Even with a lock, always write layouts defensively - OS policies and foldables can still change effective viewport size.
Platform.isPad is reliable on iOS but has no Android equivalent. For cross-platform tablet layouts, width breakpoints are the portable choice. Platform.isPad is fine for iOS-only branching (e.g., popover vs sheet).
Users can enlarge system text in accessibility settings. fontScale on useWindowDimensions reflects this multiplier. Avoid fixed-height rows that clip enlarged text; prefer wrapping and flexShrink.
Not natively. Simulate them with useWindowDimensions + breakpoint constants, or use libraries like react-native-media-query on web targets. For iOS/Android, hook-based breakpoints are the standard pattern.
const { width } = useWindowDimensions();
const modalWidth = Math.min(width - 48, 560);
<View style={{ width: modalWidth, alignSelf: "center" }} />scale is the pixel ratio (same as PixelRatio.get()). fontScale is the user accessibility text scaling factor. Both are included in the hook return value.
Set image dimensions relative to column width (calculated from useWindowDimensions) rather than fixed global pixels. See Images & Assets for asset sizing guidance.