React Basics | Part - 3

elwinjyot

Elwin Jyothis

Posted on February 20, 2022

React Basics | Part - 3

Hey developer, welcome to part 3 of the React Basics series. In the last part we learned to setup a React project and looked at different types of React components. In this part as promised, we will be learning about states of a component.

State of a Component
As discussed in the earlier parts, React has the ability to render values of variables in an HTML template. This funtionality can be performed with the help of state of a component.

Let's take an example of our Cart component.

src/components/Cart.jsx

import React from 'react';

export default class Cart extends React.Component {
    render () {
        return (
            <h1>Hello, John</h1>
        )
    }
}
Enter fullscreen mode Exit fullscreen mode

Localhost

Browser Result

Here, the name john is hard coded into the template(in the render function). But let's say this name John should change when user interacts with the webapp. In order to do this we use the amazing power of Component State. We can define a variable which will hold this changing name and just simply call the variable in the template. Let us do that then.

Before that we need to understand the basic idea of how a constructor in classes work.

A constructor, in simple words, is a set of instructions to run as soon as a class is called. These instructions can be creating essential variables, calling APIs to store essential data for the application/component and many more. In our case we will initialize a state for our component. Let us analyze the below snippet.

src/components/Cart.jsx

import React from 'react';

export default class Cart extends React.Component {
    constructor () {
        this.state = {}
    }

    render () {
        return (
            <h1>Hello, John</h1>
        )
    }
}
Enter fullscreen mode Exit fullscreen mode

You can see a constructor keyword before the render method. This is how we define a constructor for a particular class in JavaScript. Inside the curly braces, we will define all the instructions to run at call. Here we can see a variable getting initialized this.state which is assigned to...well..two curly braces 😕. This is actually how we define objects in JavaScript.
An object is a collection of key-value pairs, just like normal variables assigned to a value, in simple words it acts kind of like a collection of variables. So just like a variable, we can call a key in an object and get the assigned value. Now inside the this.state object, we will be creating all the variables that we need to use in the template. Let us understand it with a code snippet.

src/components/Cart.jsx

import React from 'react';

export default class Cart extends React.Component {
    constructor () {
        this.state = {
            first_name: "John"
        }
    }

    render () {
        return (
            <h1>Hello, John</h1>
        )
    }
}
Enter fullscreen mode Exit fullscreen mode

Here we created a key named first_name and assigned a string value "John" to it. Calling this key is pretty simple. As we learned, an object is a collection of key-value pairs, which basically means we should be storing this collection somewhere. So in this case we stored it in the variable this.state. In order to call a key inside an object, we first have to refer to the variable holding the object followed by the name of the key you want to call. There are multiple ways to refer to a key in an object

  • using the normal object.<key_name> method
  • using the indexing method.
// Object
this.state = {
    first_name: "John"
}

// Method 1
this.state.first_name

// Method 2
this.state["first_name"]
Enter fullscreen mode Exit fullscreen mode

For sometime we will be using method 1 and afterwards when the situation arises we will use method 2. Yes! These methods has to be used based on some situation. It's nothing complicated, we can do this!!!

Let us call the the first_name key in our HTML template. We will have to use a weird syntax to do this. Let us analyze the below given snippet.

src/component/Cart.jsx

import React from "react";

export default class Cart extends React.Component {
  constructor() {
    super();
    this.state = {
      first_name: "John",
    };
  }

  render() {
    return <div>Hello, {this.state.first_name}</div>;
  }
}
Enter fullscreen mode Exit fullscreen mode

In the above code snippet, you can see how a variable is called inside the render function. You should use curly braces and write the name of the variable you want to call.

Feeling a little suspicious 🧐?
Just a meme

Check out line number 5. You see a super() keyword. This is to setup all the functions and variables inherited from the React.Components object. Have you wondered why is there a this keyword before the state variable. The this keyword is used to access objects, variables and functions created in the class. Yes you directly cannot access the state variable. Now if you check the browser, uhmmm...nothing has changed, lets try changing the value of the first_name key to, let us say Sarah.

src/component/Cart.jsx

import React from "react";

export default class Cart extends React.Component {
  constructor() {
    super();
    this.state = {
      first_name: "Sarah",
    };
  }

  render() {
    return <div>Hello, {this.state.first_name}</div>;
  }
}
Enter fullscreen mode Exit fullscreen mode

Localhost

Browser Result

Yeheheee 😉, look how it changed to the new value Sarah. This is how React renders HTML dynamically. How about we take this a level up.
Just a meme

First 1 - let us add a button which will change the value of first_name when clicked.

src/component/Cart.jsx

import React from "react";

export default class Cart extends React.Component {
  constructor() {
    super();
    this.state = {
      first_name: "Sarah",
    };
  }

  render() {
    return (
      <>
        <div>Hello, {this.state.first_name}</div>
        <button>Change name</button>
      </>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Step 2 - create a function which will change the name.
In a React component, we can create different functions for different tasks and call them inside the HTML template or call it normally also. Lets create a function to do this.

src/component/Cart.jsx

import React from "react";

export default class Cart extends React.Component {
  constructor() {
    super();
    this.state = {
      first_name: "Sarah",
    };
  }

  change_name = () => {
      this.setState({ first_name: "John" });
  }

  render() {
    return (
      <>
        <div>Hello, {this.state.first_name}</div>
        <button>Change name</button>
      </>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

Whoa whoa whoa what just happened 😵
Just a meme

Yeah, just added a function.
If you are familiar with JavaScript, you might wonder where is the function keyword. Here is how react works, the "thing" you just saw is called an arrow function. If you want to read more about arrow function click here. If you have to access the variables of a class, you should be able to access the this object. But when you create a function inside a class, you lose context to the this object. Now if we bind or tie the this object whenever we create a function inside a class, we will be able to access it inside the function. This is more like a React thing. There are multiple ways of binding the this object. Below is a simple snippet showing that.

// Method 1
export default class App extends React.Component {
    constructor (props) {
        super(props);
        this.state = {
            first_name: "John"
        }
        this.change_name.bind(this);
    }

    change_name = function () {
        // do something
    }

    render () {
        return (
            <h1>Hello, { this.state.first_name }</h1>
        )
    }
}

// Method 2
export default class App extends React.Component {
    constructor (props) {
        super(props);
        this.state = {
            first_name: "John"
        }
    }

    change_name = () => {
        // do something
    }

    render () {
        return (
            <h1>Hello, { this.state.first_name }</h1>
        )
    }
}
Enter fullscreen mode Exit fullscreen mode

In method 1, we have used a normal syntax of creating a function. But in method 2, we have used the arrow function to create a function. While using method 1, you will have to manually bind the this object to the function in the constructor with the bind function. But this is not the case for method 2, it automatically binds it to the function. We will be using method 2 in this series. Let us get back to our app.

src/component/Cart.jsx

import React from "react";

export default class Cart extends React.Component {
  constructor() {
    super();
    this.state = {
      first_name: "Sarah",
    };
  }

  change_name = () => {
      this.setState({ first_name: "John" });
  }

  render() {
    return (
      <>
        <div>Hello, {this.state.first_name}</div>
        <button>Change name</button>
      </>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

This is where we were!
Inside the change_name function I we have added some code. In react we cannot directly reassign values of state keys. We have to use the setState function to change the state. So you can just simply call the this.setState() function and pass in an object with the key as the key you want to change the value of followed by the value as the new value.
Just a meme

Step 3 - Bind the change_name function to the button

src/component/Cart.jsx

import React from "react";

export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      first_name: "Sarah",
    };
  }

  change_name = () => {
      this.setState({ first_name: "John" });
  }

  render() {
    return (
      <>
        <div>Hello, {this.state.first_name}</div>
        <button onClick={this.change_name}>Change name</button>
      </>
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

We are going to use the onClick attribute of <button> element. The value of the attribute should be inside curly braces and keep in mind not to call the function with paranthesis, just end it with the name of the function only. If you add the paranthesis after the function name, it will be called immediately after the component is rendered.

It's time to check the browser

Localhost -- before

Browser Result

Localhost -- after

Browser Result

That's it for todayyyy!!
Drop your queries as comments.

Thank you for your time ☺️

Part 4 -->

💖 💪 🙅 🚩
elwinjyot
Elwin Jyothis

Posted on February 20, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related