Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
menu
  1. Home
  2. /Web Development
  3. /React
  4. /Intro To State
Your Progress0%
0 of 42 completed

React Topics

Getting Started

  • What is React?
  • React vs Vanilla JavaScript
  • Setting Up Your Environment
  • Your First React App

JSX Fundamentals

  • Introduction to JSX
  • JSX Expressions and Variables
  • Conditional Rendering
  • Lists and Keys
  • Styling in JSX

Components Basics

  • Function Components
  • Props
  • Children Prop
  • Props Destructuring
  • Component Composition

State Management

  • Introduction to State
  • useState Hook
  • State Updates and Re-renders
  • Multiple State Variables
  • State Best Practices

Events and Interactivity

  • Handling Events
  • Event Objects
  • Forms in React
  • Form Validation

Side Effects and Data

  • Introduction to useEffect
  • Data Fetching
  • Cleanup Functions
  • Dependency Arrays

Advanced Hooks

  • useRef Hook
  • useContext Hook
  • useMemo Hook
  • useCallback Hook

React Patterns

  • Custom Hooks
  • Higher-Order Components
  • Render Props Pattern

React Router

  • Introduction to React Router
  • Routes and Navigation
  • Dynamic Routes and Parameters

Best Practices

  • Component Organization
  • Performance Optimization
  • Error Handling
  • Testing React Components

Real World Project

  • Building a Complete App

Introduction to State

Making your components interactive and dynamic

So far, your React components have been static - they display the same thing every time they render. But real applications need to be interactive: buttons should respond to clicks, forms should remember user input, counters should increment. This is where state comes in. State is data that can change over time, and when it changes, React automatically updates your UI. In this lesson, you'll learn what state is, why it's essential, and how it makes your components come alive.

The Problem: Static Components

Let's try to build a simple counter that doesn't work:

broken-counter.jsx
function Counter() {
  let count = 0  // Regular variable
  
  const increment = () => {
    count = count + 1
    console.log(count)  // This logs the new value
  }
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  )
}

// Problem: When you click the button:
// - count DOES increase (you can see it in console)
// - But the UI doesn't update!
// - It stays stuck at 0

Why doesn't this work? The variable count does increase, but React doesn't know it changed. React only re-renders components when state changes, not when regular variables change.

Key Insight:

Regular JavaScript variables don't trigger re-renders. When you change a variable, React doesn't know about it, so the UI stays the same. You need state to tell React "Hey, something changed - update the UI!"

What is State?

State is data that:

  • Belongs to a component - Each component can have its own state
  • Can change over time - Unlike props, which are read-only
  • Triggers re-renders - When state changes, React updates the UI
  • Persists between renders - State values are remembered
  • Is local and private - Other components can't see or modify it

Think of state like memory:

• Props are like arguments passed to a function - they come from outside and can't be changed
• State is like variables inside a function - they're created and controlled by the component itself

Real-World State Examples

1. User Interface State

  • Is a modal open or closed?
  • Which tab is currently selected?
  • Is the menu expanded or collapsed?
  • Is dark mode enabled?

2. Form State

  • What text is in the input field?
  • Which checkboxes are checked?
  • What option is selected in the dropdown?
  • Are there any validation errors?

3. Data State

  • List of items in a shopping cart
  • Current user information
  • Messages in a chat
  • Search results

4. Loading and Error State

  • Is data currently loading?
  • Did an error occur?
  • What's the error message?
  • Is the operation complete?

State vs Props

It's important to understand the difference between state and props:

state-vs-props.jsx
// Props - passed from parent, read-only
function Greeting({ name }) {
  // name is a prop - you can read it but not change it
  // name = "New Name"  // ❌ Error! Props are read-only
  
  return <h1>Hello, {name}!</h1>
}

<Greeting name="Alice" />  // Parent controls the name


// State - owned by component, can be changed
function Counter() {
  // count is state - the component can change it
  const [count, setCount] = React.useState(0)
  
  const increment = () => {
    setCount(count + 1)  // ✅ Component controls its own state
  }
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  )
}

Key Differences

Props:

  • Passed from parent component
  • Read-only (immutable)
  • Controlled by the parent
  • Like function parameters

State:

  • Created inside the component
  • Can be changed (mutable)
  • Controlled by the component itself
  • Like local variables that trigger re-renders

How State Works

Here's what happens when you use state in React:

  1. Component renders - React calls your component function
  2. State is initialized - State starts with its initial value
  3. User interacts - User clicks a button, types text, etc.
  4. State updates - You call the state setter function
  5. React re-renders - React calls your component function again
  6. UI updates - React updates the DOM with new values
state-flow.jsx
function Counter() {
  console.log('Component rendering...')
  
  // Step 1 & 2: Component renders, state initializes to 0
  const [count, setCount] = React.useState(0)
  
  const increment = () => {
    // Step 3 & 4: User clicks, state updates
    setCount(count + 1)
    // Step 5 & 6: React re-renders, UI updates
  }
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  )
}

// Flow:
// 1. Initial render → count = 0
// 2. User clicks button
// 3. setCount(1) is called
// 4. React re-renders component
// 5. count = 1
// 6. UI shows "Count: 1"

State Preview: useState Hook

We'll dive deep into useState in the next lesson, but here's a quick preview of how you create state:

useState-preview.jsx
function Example() {
  // Create state with useState
  const [value, setValue] = React.useState(initialValue)
  //     ↑       ↑                            ↑
  //  current  setter                   starting value
  //  value    function
  
  // Examples:
  const [count, setCount] = React.useState(0)
  const [name, setName] = React.useState('')
  const [isOpen, setIsOpen] = React.useState(false)
  const [items, setItems] = React.useState([])
  
  return <div>...</div>
}

The useState hook returns an array with two values:

  • The current state value (e.g., count)
  • A function to update it (e.g., setCount)

💡 Array Destructuring

const [count, setCount] = React.useState(0)
This uses JavaScript array destructuring. It's equivalent to:
const state = React.useState(0)
const count = state[0]
const setCount = state[1]

When to Use State

✅ Use State For:

  • Data that changes over time
  • User input and form data
  • UI state (modals, tabs, menus)
  • Fetched data from APIs
  • Toggle states (on/off, open/closed)
  • Counters, timers, and animations
  • Shopping cart items
  • Selected items or options

❌ Don't Use State For:

  • Data that never changes (use constants)
  • Data from props (props are already reactive)
  • Computed values (calculate from existing state)
  • Values that don't affect rendering
when-state.jsx
function Example() {
  // ✅ Good - needs to change and affect UI
  const [count, setCount] = React.useState(0)
  const [username, setUsername] = React.useState('')
  const [isLoading, setIsLoading] = React.useState(false)
  
  // ❌ Bad - never changes, use const
  const [appName, setAppName] = React.useState('My App')
  // ✅ Better
  const appName = 'My App'
  
  // ❌ Bad - computed from state, don't duplicate
  const [count, setCount] = React.useState(0)
  const [doubleCount, setDoubleCount] = React.useState(0)
  // ✅ Better - just calculate it
  const [count, setCount] = React.useState(0)
  const doubleCount = count * 2
  
  // ❌ Bad - comes from props
  const [userProp, setUserProp] = React.useState(props.user)
  // ✅ Better - just use props directly
  const { user } = props
  
  return <div>...</div>
}

Core State Principles

1. State is Isolated and Private

Each component instance has its own state. If you render the same component twice, each has independent state:

isolated-state.jsx
function Counter() {
  const [count, setCount] = React.useState(0)
  
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  )
}

function App() {
  return (
    <div>
      <Counter />  {/* Has its own count */}
      <Counter />  {/* Has its own separate count */}
    </div>
  )
}

// Clicking button in first Counter doesn't affect second Counter!

2. State Updates are Asynchronous

async-updates.jsx
function Counter() {
  const [count, setCount] = React.useState(0)
  
  const handleClick = () => {
    setCount(count + 1)
    console.log(count)  // Still shows OLD value!
    // State update happens later
  }
  
  return (
    <button onClick={handleClick}>
      Count: {count}
    </button>
  )
}

// When you click:
// 1. setCount(1) is called
// 2. console.log(count) runs → shows 0 (old value)
// 3. Later, React re-renders with count = 1

3. State is Immutable

You should never modify state directly. Always use the setter function:

immutable-state.jsx
function Example() {
  const [count, setCount] = React.useState(0)
  const [user, setUser] = React.useState({ name: 'Alice' })
  
  // ❌ Never do this - mutating state directly
  count = count + 1
  user.name = 'Bob'
  
  // ✅ Always use setter function
  setCount(count + 1)
  setUser({ ...user, name: 'Bob' })
}

Interactive Demo

ReactPlayground.jsx
Code Editor
Preview

💡 Tip: Edit the code above and click "Run" to see your changes

Building a Mental Model

To really understand state, here's a helpful mental model:

Think of React Components Like Functions

mental-model.jsx
// Regular function
function add(a, b) {
  return a + b
}

add(2, 3)  // Returns 5
add(2, 3)  // Returns 5 again - same inputs, same output


// React component without state - like a pure function
function Greeting({ name }) {
  return <h1>Hello, {name}!</h1>
}

<Greeting name="Alice" />  // Always renders "Hello, Alice!"
<Greeting name="Alice" />  // Same input, same output


// React component with state - has "memory"
function Counter() {
  const [count, setCount] = React.useState(0)  // Memory!
  
  return (
    <div>
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>+</button>
    </div>
  )
}

// First render: shows 0
// After click: shows 1 (remembers the click!)
// After another click: shows 2 (remembers both clicks!)

State is Like a Snapshot

Each render is like a photograph of your component at a moment in time. The state values in that render won't change - they're frozen in that snapshot.

snapshot.jsx
function Counter() {
  const [count, setCount] = React.useState(0)
  
  const handleClick = () => {
    // In THIS render, count is 0
    setCount(count + 1)  // Schedule next render with count = 1
    setCount(count + 1)  // Still using count = 0!
    setCount(count + 1)  // Still count = 0!
    
    // All three use count = 0, so next render shows 1, not 3!
  }
  
  return <button onClick={handleClick}>{count}</button>
}

// This is because count doesn't change during a render
// It's locked to the value it had when the render started

Key Takeaways

  • State is data that can change over time within a component
  • Regular variables don't trigger re-renders, state does
  • Props come from parent (read-only), state is owned by component (changeable)
  • When state changes, React re-renders the component
  • Each component instance has its own isolated state
  • State updates are asynchronous - they happen later
  • Never modify state directly - always use the setter function
  • State is like memory that persists between renders
  • Each render is a snapshot with fixed state values
  • Use state for data that changes and affects the UI
  • Don't use state for constants or computed values
  • State makes components interactive and dynamic

What's Next?

You now understand what state is and why it's essential. But you still need to learn how to actually use it!

In the next lesson, you'll learn the useState hook - React's way of adding state to your components. You'll learn:

  • How to create state variables
  • How to update state and trigger re-renders
  • How to handle different types of state (strings, numbers, booleans, objects, arrays)
  • How to make your components truly interactive

Get ready to bring your components to life with the useState hook! 🎯

Learning about state - the key to interactive React components!

Previous
Component Composition
Next
useState Hook

Never Miss a New React Tutorial

Join 2,000+ developers learning React step-by-step. Get new tutorials, tips, and exclusive resources delivered to your inbox - completely FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

React Tutorials

0 of 42 completed

Your Progress0%

Topics

Getting Started

  • What is React?
  • React vs Vanilla JavaScript
  • Setting Up Your Environment
  • Your First React App

JSX Fundamentals

  • Introduction to JSX
  • JSX Expressions and Variables
  • Conditional Rendering
  • Lists and Keys
  • Styling in JSX

Components Basics

  • Function Components
  • Props
  • Children Prop
  • Props Destructuring
  • Component Composition

State Management

  • Introduction to State
  • useState Hook
  • State Updates and Re-renders
  • Multiple State Variables
  • State Best Practices

Events and Interactivity

  • Handling Events
  • Event Objects
  • Forms in React
  • Form Validation

Side Effects and Data

  • Introduction to useEffect
  • Data Fetching
  • Cleanup Functions
  • Dependency Arrays

Advanced Hooks

  • useRef Hook
  • useContext Hook
  • useMemo Hook
  • useCallback Hook

React Patterns

  • Custom Hooks
  • Higher-Order Components
  • Render Props Pattern

React Router

  • Introduction to React Router
  • Routes and Navigation
  • Dynamic Routes and Parameters

Best Practices

  • Component Organization
  • Performance Optimization
  • Error Handling
  • Testing React Components

Real World Project

  • Building a Complete App
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo