React Series - 3 [State]
Tags: react, beginners, webdev, javascript
Published: 2021-10-12 22:44:28

State is an object in a component which holds some form of data relevant to the component it is created in.

A State object is private to the component it is created in, It can be thought of as dynamic data managed by a component, unlike props which are just ‘static’ data that you pass into the component to render some form of information.

Any modification to the value of a state object will cause the component instance it is created in to re-render itself to show the updated value.

Originally 'states' were only usable in class-based component but with the addition of a new feature called 'Hooks' gave functional component the ability to use those extra features that class-based components had.

### How to use States
Lets look at a simple project to illustrate states. Visit this [sandbox](https://codesandbox.io/s/states-example-j744g?file=/src/index.js).
It's just a simple interface for 'buying' a game.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ymrwcihfypeajbzyevlh.png)

`import React,{ useState, useRef } from 'react';`

In our component *GamePick*, we import react along with *useState* and *useRef*, both of which are React Hooks.

We also import the CSS file for our component.

In functional components, a state is defined using the 'useState()' hook. It takes in the initial value of the state as its parameter and returns an array with two values; The value passed into it as a parameter and a function which can be used for updating the state object.

> In functional components states can't be modified like normal variables, only through the use of the function that *useState* returns.


```JavaScript
const [purchaseOutput, setPurchaseOutput] = useState("No purchases made.");
const [priceVal, setPriceVal] = useState();
const currentProduct = useRef("");
```
In the definition of our component, we create a state and using de-structuring; We pass it into a variable *purchaseOutput*, and give also pass its updating function into variable *setPurchaseOutput*.

Another state is also created which will handle prices of the products. We will like for the price in the input element to be changed when a different option is selected.

We define a `ref` object `currentProduct` using the `useRef()` hook. It is responsible for knowing what the current selected option is.

> useRef() essentially lets us define an object that exists throughout the lifetime of the component instance it is defined in. In this case, think of it as being similar to `useState` except that when a `ref` objects' value is updated/modified, it doesn't cause the component to re-render itself. The value of an object created using `useRef` is accessed and modified using the `.current` method not a function like states. A proper [explanation](https://www.react.express/hooks/useref).

Moving ahead to the JSX code, we have a simple select element along with a disabled input element and a button, all enclosed in divs' and given classes for styling. The states are put where they are needed in the JSX code.

> `className` is the equivalent of writing a normal class attribute in HTML

In our select element, we listen for the `onChange` event and call `selectHandler` function when an option is picked.
```JavaScript
const selectHandler = (event) => {
        setPriceVal(prices[event.target.value]);
        currentProduct.current = event.target.value;
    }
```
In the `selectHandler` function, we simply update the value of the `priceVal` state (which is the value shown in the input element) and we update `currentProduct` and set it's value to the current option selected.

We also listen for an `onClick` event on the button and call `buyHandler` function when it is triggered.
```JavaScript
const buyHandler = () => {
        if (currentProduct.current !== "")
        {
            setPurchaseOutput(`${products[currentProduct.current]} purchased for ${prices[currentProduct.current]}.`);
        }
    }
```
Here we're simply updating the `purchaseOutput` state only if the option selected isn't the default value in the <select> element.

Try out the app in the sandbox to understand the code better.

Comment below if you didn't understand something properly and I will try to help you. Thanks for reading