Skip to main content

Learning Objectives

By the end of this module, you’ll understand:
  • Local state with useState and useReducer
  • Context API patterns
  • Prop drilling solutions
  • When to use global state

Local State

useState Pattern

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <View>
      <Text>Count: {count}</Text>
      <Button title="+" onPress={() => setCount(c => c + 1)} />
    </View>
  );
}

useReducer for Complex State

import { useReducer } from 'react';

const initialState = { loading: false, data: null, error: null };

function dataReducer(state, action) {
  switch (action.type) {
    case 'FETCH_START':
      return { ...state, loading: true };
    case 'FETCH_SUCCESS':
      return { ...state, loading: false, data: action.payload };
    case 'FETCH_ERROR':
      return { ...state, loading: false, error: action.payload };
    default:
      return state;
  }
}

Context API

Creating Context

const ThemeContext = createContext(null);

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');

  const value = {
    theme,
    toggleTheme: () => setTheme(t => t === 'light' ? 'dark' : 'light'),
  };

  return (
    <ThemeContext.Provider value={value}>
      {children}
    </ThemeContext.Provider>
  );
}

Best Practices

  1. Start local, lift when needed
  2. Use context for truly global state
  3. Avoid prop drilling with composition
  4. Keep state minimal - derive when possible