React Series - #3 [State]

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. It's just a simple interface for 'buying' a game. image

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.

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.

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.

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.

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 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