Topic Overview and Plan

Welcome! Today, we'll journey deeper into React, focusing on props, state updates, and conditional state updates. Our itinerary includes:

  1. A review of props.
  2. An explanation of the previous state.
  3. The handling of state updates based on the previous state.
  4. Conditional state updates based on the previous state.
Review of `props` in Functional Components

In our React journey, props act as a suitcase, carrying items from parent to child components. However, props are read-only—the data passed from the parent to the child should not be changed by the child.

// Child Component
function ChildComponent(props) {
  return <p>{props.message}</p>;
}

// Parent Component
function ParentComponent() {
  return <ChildComponent message="Hello there!" />
}

ParentComponent(); // Renders: Hello there!

In this example, ParentComponent sends a message via props to ChildComponent, which then displays it.

Previous State: The Key to Dynamic State Management

In React, the previous state helps us understand changes in state over time. When managing React state, the concept of the previous state becomes crucial due to the asynchronous nature of setState events.

Consider this Counter component:

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);
  const handleClick = () => { 
    setCount(count + 1); // Here, count is the previous state
  };
  return (
    <div>
      <p>You clicked {count} times</p> {/* Displays the count */}
      <button onClick={handleClick}>Click me</button> {/* Increments the counter when clicked */}
    </div>
  );
}

This Counter uses the previous count to calculate the new count.

State Update based on Previous State

Imagine you're navigating through a labyrinth. At times, your next move depends not just on your present location but also on how you got there — your previous state.

In React, too, your component's next state often depends on the previous one. Why? Because setState updates might be asynchronous. This means that JavaScript doesn't immediately update the current state and re-render the component when setState is called. Instead, it schedules these operations for future execution and proceeds to the next line of code. This future execution can lead to errors when a subsequent state update depends on the change just scheduled. It’s like planning to take a right turn based on a preceding left turn, but the left hasn't been taken yet.

That's when we base the state update on the previous state. By passing a function to setState, we ensure accurate updates even with asynchronous modifications. This function receives the previous state value, performs the necessary state update operations, and returns the new state value.

To optimize our Counter component, consider this variant of handleClick:

const handleClick = () => {
  setCount(prevCount => prevCount + 1);
};

In handleClick, we pass a function to setCount. This function takes prevCount (the previous count) as an argument and returns prevCount + 1, ensuring count incrementation based on the correct previous count. So, no matter when JavaScript executes this state update, it derives the new count accurately from the confirmed previous count.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal