avatarJoanna Marie

Summary

This context discusses the anti-pattern of using props in the initial state in React, highlighting the problems it can cause and providing an example to illustrate the issue.

Abstract

React props are a mechanism for passing data from parent to child components, and they are read-only. However, using props to define the initial state of a child component can lead to duplicated sources of truth and inconsistencies when the parent component's props change. This context explains the problems associated with this anti-pattern and provides an example of a parent and child component to demonstrate the issue. The example shows that if the parent component's state changes, the child component's state does not update, leading to a lack of clarity. The context concludes with two rules to follow when using props as initial state: only pass props that will not change in the future and give props explicit names to make intentions clear.

Bullet points

  • React props are a mechanism for passing data from parent to child components.
  • Props are read-only and cannot be modified by the child component.
  • Using props to define the initial state of a child component can lead to duplicated sources of truth and inconsistencies.
  • If the parent component's props change, the child component's state does not update.
  • Initial value of the state is only used during the first rendering of the component.
  • Two rules to follow when using props as initial state:
    • Only pass props that will not change in the future.
    • Give props explicit names to make intentions clear.

React Anti-Patterns: Props In Initial State

Photo by JJ Ying on Unsplash

Knowing best practises is always valuable, but sometimes more important is being aware of anti-patterns. By familiarizing ourselves with anti-patterns, we not only steer clear of common traps but also build a deeper understanding of what we code.

In React, “props” (short for “properties”) are a mechanism for passing data from a parent component to a child component. Props are read-only, meaning that they cannot be modified by the child component that receives them. However, they can be used to define initial state of the child component. It looks innocent, but it may lead to lack of clarity.

In general, when this approach is not implemented correctly, it can lead to two problems:

  • we have duplicated source of truth — props from the parent component and state from the child component.
  • if the props passed to the child component changes, the state in the child component does not get updated.

Example

Let’s see an example:

function ChildComponent(props) {
  const [inputNumber, setInputNumber] = useState(props.number);

  const inputChangedHandler = (event) => {
    setInputNumber(event.target.value);
  };
  
  return (
    <div>
      <input type='number' onChange={inputChangedHandler} />
      <p>Input number: {inputNumber}</p>
    </div>
  );
}

function ParentComponent() {
  const [randomNumber, setRandomNumber] = useState(0);
  
  const clickedHandler = (event) => {
    setRandomNumber(Math.round(Math.random(0,100)*1000));
  };

  return (
    <div>
      <button onClick={clickedHandler}>
        Generate Random Number
      </button>
      <p>Random number: {randomNumber}</p>
      {
        randomNumber >= 500 && <ChildComponent number={randomNumber} />
      }
    </div>
  );
}

Run the code

You can run this code in the sandbox:

How it works?

When you click the “Generate Random Number” button in the ParentComponent, it generates a random integer between 0 and 1000 and updates the randomNumber state.

If randomNumber is 500 or greater, the ChildComponent is displayed, and it sets its inputNumber state to the value of randomNumber when it first renders. However, any subsequent changes to randomNumber in the ParentComponent won't automatically affect the inputNumber in the ChildComponent.

Initial value of the state is only used during the first rendering of the component. If you destroy and recreate the ChildComponent, then the initial props will be used again. This means that props used to initialize state are only applied once, and after that, state and props are separate.

Conclusion

In this article, we learned why using props as initial state is considered an anti pattern. Overall, there are two rules to follow:

  • pass only those props, for which you are sure that they will not change in the future.
  • if you cannot avoid changing of props, give it explicit name eg. initalValue, that makes your intention clear.
React
Reactjs
JavaScript
Software Development
Software Engineering
Recommended from ReadMedium