#8 Lifting State Up in React

In React, state management is a crucial aspect of building dynamic and interactive user interfaces. One common challenge developers face is sharing state between components. This can be efficiently handled by a technique known as “lifting state up.” In this article, we’ll explore what lifting state up means, why it’s important, and how to implement it with practical examples.

What is Lifting State Up?

Lifting state up refers to moving the state to the closest common ancestor of the components that need to share it. Instead of maintaining state in multiple components, you keep it in a single component and pass it down as props. This ensures a single source of truth and makes the application easier to manage and debug.

Why Lifting State Up is Important

  • Single Source of Truth: By having state in one place, you avoid inconsistencies and make debugging easier.
  • Data Flow Management: It simplifies the flow of data, ensuring that components that need to interact share a consistent state.
  • Reusability: Components become more reusable as they don’t manage their state, making them easier to test and maintain.

Example: Sharing State Between Components

Let’s consider an example where we have two components, TemperatureInput and BoilingVerdict. We’ll lift the state up to a common ancestor, Calculator.

Step 1: Create the Components

  1. TemperatureInput Component
import React from 'react';

function TemperatureInput({ temperature, scale, onTemperatureChange }) {
  const scaleNames = {
    c: 'Celsius',
    f: 'Fahrenheit'
  };

  const handleChange = (e) => {
    onTemperatureChange(e.target.value);
  };

  return (
    <fieldset>
      <legend>Enter temperature in {scaleNames[scale]}:</legend>
      <input value={temperature} onChange={handleChange} />
    </fieldset>
  );
}

export default TemperatureInput;

2. BoilingVerdict Component

import React from 'react';

function BoilingVerdict({ celsius }) {
  if (celsius >= 100) {
    return <p>The water would boil.</p>;
  }
  return <p>The water would not boil.</p>;
}

export default BoilingVerdict;

Step 2: Lift State Up to the Common Ancestor

  1. Calculator Component
    import React, { useState } from 'react';
    import TemperatureInput from './TemperatureInput';
    import BoilingVerdict from './BoilingVerdict';
    
    function toCelsius(fahrenheit) {
      return (fahrenheit - 32) * 5 / 9;
    }
    
    function toFahrenheit(celsius) {
      return (celsius * 9 / 5) + 32;
    }
    
    function tryConvert(temperature, convert) {
      const input = parseFloat(temperature);
      if (Number.isNaN(input)) {
        return '';
      }
      const output = convert(input);
      const rounded = Math.round(output * 1000) / 1000;
      return rounded.toString();
    }
    
    function Calculator() {
      const [temperature, setTemperature] = useState('');
      const [scale, setScale] = useState('c');
    
      const handleCelsiusChange = (temperature) => {
        setTemperature(temperature);
        setScale('c');
      };
    
      const handleFahrenheitChange = (temperature) => {
        setTemperature(temperature);
        setScale('f');
      };
    
      const celsius = scale = = = 'f' ? tryConvert(temperature, toCelsius) : temperature;
      const fahrenheit = scale = = = 'c' ? tryConvert(temperature, toFahrenheit) : temperature;
    
      return (
        <div>
          <TemperatureInput
            scale="c"
            temperature={celsius}
            onTemperatureChange={handleCelsiusChange}
          />
          <TemperatureInput
            scale="f"
            temperature={fahrenheit}
            onTemperatureChange={handleFahrenheitChange}
          />
          <BoilingVerdict
            celsius={parseFloat(celsius)}
          />
        </div>
      );
    }
    
    export default Calculator;
    

    Explanation

    • TemperatureInput: This component renders an input field for temperature. It receives temperature, scale, and onTemperatureChange as props. The onTemperatureChange prop is a function to update the temperature state in the parent component.
    • BoilingVerdict: This component displays whether the water would boil at the given temperature. It receives celsius as a prop.
    • Calculator: This is the common ancestor component that lifts the state up. It maintains the temperature and scale state and passes them down to the TemperatureInput components as props. It also contains the logic to convert temperatures between Celsius and Fahrenheit and displays the BoilingVerdict.

    Conclusion

    Lifting state up is a powerful technique in React for managing shared state between components. By moving state to a common ancestor, you can ensure a single source of truth and simplify the flow of data in your application. In this article, we demonstrated how to lift state up using a practical example involving temperature inputs and a boiling verdict. By applying this technique, you can build more maintainable and scalable React applications.

    Hashtags

    #React #StateManagement #LiftingStateUp #WebDevelopment #JavaScript #ReactJS #FrontendDevelopment #Programming #Coding #SoftwareDevelopment #ReactComponents #DataFlow #UIDevelopment

    Leave a Reply