React State vs Props

Published on
6 mins read
––– views

What are Props and State?

In short, props are inputs that we pass into components from their parent. State is the internal data that changes and re-renders the component.

Props

On every single React tutorial you will hear passing props, its almost like React is all about passing props. Word props is short for properties. In very simple terms, they are like attributes that we passed to HTML elements, like class. Props can contain different types of data, such as text, numbers, or functions, and can be passed down to nested components.

<div class="main-section"></div>

Imagine a bucket full of water and a garden. If the bucket represents props, and the plants represent components, then watering the plants is like passing props or data to them. Without water, most plants will die, and without data, most apps won't function.

<Button variant="primary">
          Accept
</Button>
 <Button variant="secondary">
          Decline
</Button>

We have two buttons here, with the variant prop being used to control their behavior and appearance. By passing primary and secondary values to the buttons, we can modify what they do and how they look, which is similar to passing CSS classes.

However, the variant prop can contain more than just styling - it can also include data and functions.

In summary, props are similar to CSS classes, but they are much more powerful and flexible. They allow you to pass data and functionality to components, making it easier to create highly customizable and reusable code.


State

Imagine visiting a beer company's website. In most countries, the company is required by law to ask for your age, as it is illegal to display alcoholic beverages to minors.

A pop-up window appears, asking you to enter your age or click on a button that says "Yes, I'm over 21 years old," at least in the 🇺🇸.

By clicking on that button, you will change the state of the component. If you click on "I'm over 21," app's state will change, and the website will be displayed. If not, you might be kicked out of the website."

Here is an example code if you would like to check it out. It's too long to post in here. Example code

Never mutate React State

React doesn't care what type of data you bind to state - it can handle anything from data to numbers and even functions. Although, if you're using functions, it's best to use useCallback to avoid any headaches.

It's important to be mindful of mutations. While you can mutate the state and it may work for your needs, it's not recommended. React relies on the fact that you're a cool developer who would never mutate the state. Therefore, it won't warn you about it if you do so. However, bugs caused by state mutation can be difficult to track down and fix.

When a component randomly renders or doesn't render, updates or doesn't update, it's like playing lottery. This can lead to confusion and frustration when trying to diagnose a problem. A quick fix by mutating the state can cause you endless hours and debugging time. That's why it's best to never mutate the React state, as it can save you loads of trouble in the long run.

Take a look at this code, and I will explain it line by line below. It isn't the full code because it would have too much boilerplate and my goal here is to explain how stuff works with minimal code.

const [currentColor, setCurrentColor] = React.useState(['#aaaaaa', '#bbbbb', '#ccccc'])

//// map function is used to get colors from currentColor
 {currentColor.map((color, index) => {
          const colorTable = \`color-\${index}\`;
///
////
<input
  id={colorTable}
  type="color"
  value={currentColor}
  onChange={(event) => {
    const updatedColors = [...currentColor]
    updatedColors[index] = event.target.value
    setCurrentColor(updatedColors)
  }}
/>

Let's break this code down:

You are probably familiar with this part. We have a useState("") and it's in array form. In the array, we have 3 colors, with their HEX values.

We have an input, and it is a browser's build in color picker. User will be able to pick colors. We know that from type="color".

value is set to currentColor, which is the default state of our useState hook.

const [currentColor, setCurrentColor] =
  React.useState(['#aaaaaa', '#bbbbb', '#ccccc'])
///


  <input
  id={colorTable}
  type="color"
  value={currentColor}
  />


{currentColor.map((color, index) => {
          const colorTable = \`color-\${index}\`;

onChange={(event) => {
    const updatedColors = [...currentColor]
    updatedColors[index] = event.target.value
    setCurrentColor(updatedColors)
  }}

}

Let's examine this part

  • We have an onChange function, which get's invoked when there is an event.

  • When there is an event, we create a new variable/array called updatedColors.

  • updatedColors variable is equal to our useState() hook, which is in array form. Since it is an array, we get it's data with ..., the spread operator. [...currentColor]

  • [index] comes from the .map function. updatedColors[index] set's a color to the event.target.value

  • Finally, we set the state with setCurrentColor

Okay, but why?

I can hear you asking, why are we mapping and creating a new array, and getting the values with the spread operator? What is the point of this?

If we directly mutate the currentColor array that comes from the useState hook, it will cause problems. React relies on the fact that you will never mutate the state directly.

So, we need to create an exact copy of the currentColor array and modify the copy. Which is updatedColors, and update our setCurrentColor with the updatedColors. With this implementation, React will receive a new object after each render and React will continue to control it's own state and we won't get involved in it's business. React like to perform it's magic under the hood, try not to touch it.

In short summary:

  • Modifying the currentColor array is bad.
  • Creating a copy of the currentColor array and modifying the copy (updatedColors) is good.
  1. Make a new array
  2. Make your changes on the new array
  3. Update the state with that modified array
  4. Leave the original array alone, don't touch it.

Order is important.