tfs-demos

React State Guide

These notes are not intended as a comprehensive guide to the topic. Their purpose is to guide you through the main areas you should learn about, with resources provided for further exploration. The goal is for you to learn enough to complete the associated challenge.

These notes introduce the concept of state in React, the different ways it can be managed, and when each approach makes sense.

They build on the core React concepts you have seen previously - components, props, and hooks.


What is state?

State is data that changes over time and affects what your component renders.

Examples:

React re-renders components when state changes, so the user interface always matches the current data.

Further learning


Local state (inline, component-level)

Each component can hold its own state with the useState hook.

When to use it

Example

import { useState } from 'react'

function PlanetSearch() {
  const [query, setQuery] = useState('')

  return (
    <div>
      <input
        value={query}
        onChange={e => setQuery(e.target.value)}
        placeholder="Search planets"
      />
      <p>Searching for: {query}</p>
    </div>
  )
}

Limitations

As your app grows, you might need to share state between distant components. At first, you can “lift” the state up and pass it down through props.


Lifting state up and passing props

When multiple components need access to the same data, move the state to their nearest common ancestor and pass it down via props.

Example

function PlanetDashboard() {
  const [selectedPlanet, setSelectedPlanet] = useState(null)
  return (
    <>
      <PlanetList onSelect={setSelectedPlanet} />
      <PlanetDetails planet={selectedPlanet} />
    </>
  )
}

function PlanetList({ onSelect }) {
  return (
    <ul>
      <li onClick={() => onSelect('Jupiter')}>Jupiter</li>
      <li onClick={() => onSelect('Saturn')}>Saturn</li>
    </ul>
  )
}

function PlanetDetails({ planet }) {
  if (!planet) return <p>Select a planet to view details</p>
  return <p>Details for {planet}</p>
}

Pros

Cons

Further learning


Global state with Context

React’s built-in useContext hook lets you share state without prop drilling.

When to use it

Example

import { createContext, useContext, useState } from 'react'

const PlanetContext = createContext()

export function PlanetProvider({ children }) {
  const [planet, setPlanet] = useState('Earth')
  return (
    <PlanetContext.Provider value=>
      {children}
    </PlanetContext.Provider>
  )
}

export function usePlanet() {
  return useContext(PlanetContext)
}

// Example usage
function PlanetName() {
  const { planet, setPlanet } = usePlanet()
  return (
    <div>
      <p>Current planet: {planet}</p>
      <button onClick={() => setPlanet('Mars')}>Go to Mars</button>
    </div>
  )
}

Pros

Cons

Further learning


Scalable state management - Redux Toolkit and Zustand

For larger projects, you may outgrow Context or want more predictable state management. Two common modern solutions are Redux Toolkit and Zustand.


Redux Toolkit (RTK)

Redux Toolkit is the official, recommended way to use Redux as of 2025. It simplifies setup and reduces boilerplate compared with older Redux patterns.

When to use it

Example (Redux Toolkit)

npm install @reduxjs/toolkit react-redux
// store.js
import { configureStore, createSlice } from '@reduxjs/toolkit'

const planetsSlice = createSlice({
  name: 'planets',
  initialState: [],
  reducers: {
    addPlanet: (state, action) => {
      state.push(action.payload)
    }
  }
})

export const { addPlanet } = planetsSlice.actions

export const store = configureStore({
  reducer: { planets: planetsSlice.reducer }
})
// PlanetApp.jsx
import { Provider, useDispatch, useSelector } from 'react-redux'
import { store, addPlanet } from './store'

function PlanetList() {
  const planets = useSelector(state => state.planets)
  const dispatch = useDispatch()
  return (
    <div>
      <button onClick={() => dispatch(addPlanet('Neptune'))}>Add Neptune</button>
      <ul>{planets.map(p => <li key={p}>{p}</li>)}</ul>
    </div>
  )
}

export default function App() {
  return (
    <Provider store={store}>
      <PlanetList />
    </Provider>
  )
}

Pros

Cons

Further learning


Zustand

Zustand is a lightweight alternative to Redux Toolkit with a simpler API and minimal setup.

When to use it

Example

npm install zustand
import { create } from 'zustand'

const usePlanetStore = create(set => ({
  planets: ['Earth'],
  addPlanet: planet => set(state => ({ planets: [...state.planets, planet] }))
}))

function PlanetList() {
  const { planets, addPlanet } = usePlanetStore()
  return (
    <div>
      <button onClick={() => addPlanet('Mars')}>Add Mars</button>
      <ul>{planets.map(p => <li key={p}>{p}</li>)}</ul>
    </div>
  )
}

Pros

Cons

Further learning


Choosing the right tool

Scale Tool Typical use
Small useState Local state within a single component
Medium useContext Global state for simple settings or user info
Medium-Large Zustand Shared state with minimal setup
Large Redux Toolkit Predictable, structured global state with middleware and debugging

Top tips

Further reading