React Training Course Part 14: Workshop on Class Based Components, Component State

https://scrimba.com/playlist/p7P5Hd
  • Transfer
  • Tutorial
In this part of the translation of the React course, we suggest that you complete a practical task on working with class-based components. After that we will begin to master such an important concept of React, as the state of the components. → Part 1: course overview, reasons for the popularity of React, ReactDOM and JSXPart 2: functional componentsPart 3: component files, project structurePart 4: parent and child componentsPart 5: starting work on a TODO application, basics of stylingPart 6: About some features of the course, JSX and JavaScriptPart 7: Inline Styles

image








Part 8: continued work on a TODO application, familiarity with the properties of components
Part 9: properties of components
Part 10: a workshop on working with properties of components and styling
Part 11: dynamic formation of markup and the array method map
Part 12: workshop, third stage of working on a TODO application
Part 13: components based on classes
Part 14: a workshop on components based on classes, the state of components
Part 15: workshops on working with the state of components

Session 25. Workshop. Class Based Components


Original

▍Job


Below is the code that needs to be placed in the file of the index.jsstandard React application created by the tools create-react-app. Convert the functional components you find in this code into class-based components, and also find and fix a small error.

File ID index.js:

import React from "react"
import ReactDOM from "react-dom"
// #1
function App() {
    return (
        <div>
            <Header />
            <Greeting />
        </div>
    )
}
// #2
function Header(props) {
    return (
        <header>
            <p>Welcome, {props.username}!</p>
        </header>
    )
}
// #3
function Greeting() {
    const date = new Date()
    const hours = date.getHours()
    let timeOfDay
    
    if (hours < 12) {
        timeOfDay = "morning"
    } else if (hours >= 12 && hours < 17) {
        timeOfDay = "afternoon"
    } else {
        timeOfDay = "night"
    }
    return (
        <h1>Good {timeOfDay} to you, sir or madam!</h1>
    )
}
ReactDOM.render(<App />, document.getElementById("root"))

▍Decision


First, let's take a look at what the application gives out in its original form, opening it in the browser.


Page of the initial application in the browser

It is seen that the top line, which is displayed on the page, looks wrong. After the comma following Welcome, there obviously should be something like a username.

If you analyze the application code, it turns out that this line is displayed by the componentHeader, expecting to get the propertyusernamespecified when creating its instance. An instance of this component is created in the componentApp. Having found this out, we can correct the very mistake that was mentioned in the assignment.

It should be noted that the components are usually placed in different files, but in this case we have described them all in one file.

Let's start the transformation of the functional component.Appinto a class based component. To do this, it is enough to bring its code to this form:

class App extends React.Component {
    render() {
        return (
            <div>
                <Header username="vschool"/>
                <Greeting />
            </div>
        )    
    }
}

Before the component name now comes the keyword class, followed by the command extends React.Component, then, in curly brackets, describes the body of the class. There must be a method render()that returns what we returned from the functional component. Other components are processed in the same way. Pay attention to the design <Header username="vschool"/>. Here we pass the Headerproperty usernameto the component with a value vschool, thereby correcting the error that exists in the original application.

As you already know, the component Headerexpects to receive the property username, and in the functional component, access to this property is carried out using the construction props.username(propsin this case, it is the argument of the function describing the component). In class-based components, the same thing looks like this.props.username. Here is the revised component code Header:

class Header extends React.Component {
    render() {
        return (
            <header>
                <p>Welcome, {this.props.username}!</p>
            </header>
        )    
    }
}

The third component, a Greetingbit different from the others. The fact is that in it, before the command return, some calculations are performed. When converting it to a component based on a class, these calculations must be placed in the method render()before the return command. Here is the code for the recycled component Greeting:

class Greeting extends Component {
    render() {
        const date = new Date()
        const hours = date.getHours()
        let timeOfDay
        
        if (hours < 12) {
            timeOfDay = "morning"
        } else if (hours >= 12 && hours < 17) {
            timeOfDay = "afternoon"
        } else {
            timeOfDay = "night"
        }
        return (
            <h1>Good {timeOfDay} to you, sir or madam!</h1>
        )
    }
}

Note that when you declare that component used this design: class Greeting extends Component. Often, this is done for the sake of brevity, but in order for this to work, we need to refine the import command react, bringing it to this form:

import React, {Component} from "react"

Here’s what the redesigned browser page looks like.


The page of the redesigned application in the browser

Actually, it looks the same as the page of the original application, and the only noticeable difference between these pages is that now the firstHeadername of thecomponent that is passed to the component is displayed.

Here is the complete code of the recycled fileindex.js:

import React, {Component} from "react"
import ReactDOM from "react-dom"
// #1
class App extends React.Component {
    render() {
        return (
            <div>
                <Header username="vschool"/>
                <Greeting />
            </div>
        )    
    }
}
// #2
class Header extends React.Component {
    render() {
        return (
            <header>
                <p>Welcome, {this.props.username}!</p>
            </header>
        )    
    }
}
// #3
class Greeting extends Component {
    render() {
        const date = new Date()
        const hours = date.getHours()
        let timeOfDay
        
        if (hours < 12) {
            timeOfDay = "morning"
        } else if (hours >= 12 && hours < 17) {
            timeOfDay = "afternoon"
        } else {
            timeOfDay = "night"
        }
        return (
            <h1>Good {timeOfDay} to you, sir or madam!</h1>
        )
    }
}
ReactDOM.render(<App />, document.getElementById("root"))

If the implementation of this practical task did not cause you difficulties - great. If you are still not fully accustomed to the components based on the classes - take some time to experiment with them. For example, you can again convert components based on classes into functional components, and then perform the inverse transformation.

Lesson 26. Component Status


Original

The state is an incredibly important React concept. If a component needs to store any of its own data and to manage this data (as opposed to the situation when the data is passed to it by the parent component using the property mechanism), the state of the component is used. Today we look at the basic concepts relating to the state of the components.

A state is only data that a component manages. In particular, this means that the component can change this data. At the same time, the properties that the component receives from the parent component that are already familiar to us cannot be changed by the receiving component. They, in accordance with the documentationReact, are immutable (immutable). For example, if you try, in a component based on a class, to use a construct like this.props.name = "NoName"- we will encounter an error message.

It should be noted that if a certain component needs to work with the state, then it must be a component based on the class. Let's talk about how to equip a component with a state, starting with the following code snippet, which is the contents of a App.jsstandard project file created with the tools create-react-app:

import React from "react"
class App extends React.Component {
    render() {
        return (
            <div>
                <h1>Is state important to know?</h1>
            </div>
        )
    }
}
export default App

This is what the application page looks like in a browser.


Application page in browser

In order to equip a component with a state, you first need to create a class constructor. It looks like a class methodconstructor(). After this, the component code will look like this:

class App extends React.Component {
    constructor() {
        
    }
    
    render() {
        return (
            <div>
                <h1>Is state important to know?</h1>
            </div>
        )
    }
}
Constructor()

This is a special method embedded in JavaScript that is designed to create and initialize objects based on classes. As a matter of fact, if you need to initialize something when creating an object, the corresponding operations are performed in the method constructor().

The first thing to do in the constructor code is to call the parent class constructor. This is done using the function super(). In the constructor of the parent class, some initialization operations can be performed, the results of which will be useful to our object. Here is what the constructor of our class will now look like:

constructor() {
    super()
}

Now, in order to equip a component with a state, we need to add a property to the class instance in the constructor state. This property is an object:

constructor() {
    super()
    this.state = {}
}

Here we initialized it with an empty object. You can work with the state in the component code using the construction this.state. Add a new property to the state:

constructor() {
    super()
    this.state = {
        answer: "Yes"
    }
}

Now let's think about how to use what is stored in the state, in the code. Recall that a component displays a question Is state important to know?. The state stores the answer to this question. In order to add this answer after the question, you need to do the same as we usually do by adding JavaScript constructs to the JSX code. Namely, it is necessary to add a construction to the end of the line {this.state.answer}. As a result, the complete component code will look like this:

class App extends React.Component {
    constructor() {
        super()
        this.state = {
            answer: "Yes"
        }
    }
    
    render() {
        return (
            <div>
                <h1>Is state important to know? {this.state.answer}</h1>
            </div>
        )
    }
}

This is how the application page will look like in a browser.


Application page in the browser

Here I would like to note that the state that the component receives during initialization can be changed during the operation of the component. In addition, components can transfer state to descendant components using the mechanism of working with properties that you already know. For example, in our case, if we assume that there is a certain componentChildComponent, data from the state can be transferred to it as follows:

<ChildComponent answer={this.state.answer}/>

Until we talk in detail about how to change the data stored in the component state. We only note that when calling the method setState()used to solve this task, not only the state of the component will be changed, but also the state data transmitted via the property mechanism to its child components will be updated. In addition, a state change will cause the data from the state displayed on the application page to change automatically.

Results


Today you had the opportunity to work with class-based components. In addition, here began your acquaintance with the concept of the state of the components. The next time you are waiting for practical tasks to work with the state.

Dear readers! If you use React in practice, please tell us how you manage the state of the components. Do you use standard React or something else for this?


Also popular now: