Skip to content

Chapter 2 of 7

Hooks, State, and Side Effects

The useState hook is the foundation of local state in React Native components, returning the current value and a setter function. On subsequent renders, the initial value argument is ignored, so any expensive computation should be passed as a lazy initializer function to avoid running it on every re-render. useReducer offers an alternative for managing complex state with multiple sub-values or when the next state depends on the previous one, mirroring the Redux pattern of (state, action) => newState plus a dispatch function. useRef provides a mutable container that persists across renders without triggering a re-render, making it ideal for storing timer IDs, previous values, or references to native components.

useEffect handles side effects such as subscriptions and data fetching, accepting an effect function and an optional dependency array. The dependency array tells React which values the effect depends on, with an empty array meaning the effect runs only on mount. The cleanup function returned from the effect runs both before the component unmounts and before the effect re-runs when dependencies change, allowing you to unsubscribe from listeners, cancel timers, and abort network requests. useLayoutEffect fires synchronously after view mutations but before paint, making it suitable for measuring layouts or preventing visual flicker. useCallback and useMemo memoize functions and computed values respectively; useCallback(fn, deps) is equivalent to useMemo(() => fn, deps) and both help avoid unnecessary work when passing callbacks to memoized children.

Custom hooks let you encapsulate reusable logic across components. By naming a function starting with 'use', you can compose other hooks and return any combination of state, refs, or computed values. For example, a useFetch hook can manage data, loading, and error state while handling its own subscription lifecycle. When fetching data, AbortController allows you to cancel in-flight requests by passing its signal to fetch() and calling controller.abort() in the effect cleanup. React's StrictMode, Suspense, and React.lazy together enable code splitting and graceful loading fallbacks for rarely visited screens. Controlled components receive their value through props and notify changes via onChange, while uncontrolled components manage their own state internally and are read via refs with defaultValue, giving controlled components more predictable validation behavior.

All chapters
  1. 1Foundations of React Native
  2. 2Hooks, State, and Side Effects
  3. 3Navigation, Routing, and Screen Lifecycle
  4. 4Native Features, Data, and Device APIs
  5. 5Animations, Gestures, and Performance
  6. 6Expo, Deployment, and the New Architecture
  7. 7Debugging, Testing, and Accessibility

Drill it

Reading is not remembering. These come from the React Native Mobile deck:

Q

What is the default flex direction in a React Native View container?

The default flexDirection is 'column' in React Native, which differs from the web's default of 'row'. Children stack vertically from top to bottom unless you ch...

Q

How do you make a Text component take up the full available width of its parent?

Apply style={{flex: 1}} or alignSelf: 'stretch' to the Text component. Without these, Text only wraps its content. flex: 1 grows the component to fill remaining...

Q

What is the purpose of the SafeAreaView component?

SafeAreaView renders content within device areas not covered by notches, status bars, or home indicators. It's primarily useful on iOS devices with notches and...

Q

Explain the difference between useState and useRef for storing mutable values.

useState triggers a re-render when updated and is meant for state that affects the UI. useRef returns a mutable object (.current) that persists across renders w...