Skip to content

Latest commit

 

History

History
157 lines (124 loc) · 4.41 KB

File metadata and controls

157 lines (124 loc) · 4.41 KB

In this lesson, we will learn about state in class-based components. We will use state to hold a list of tasks and then render them as new tasks are added to it.

Let's go to our smarter-tasks react app and open VSCode using code ..

Let's first edit our Task component inside the Task.tsx file to accept a title property, so that, we can render different tasks.

Since we are using TypeScript, we will have to first create a type for the different properties this component can accept. We can use interface to do that. Let's create a TaskProp interface inside our Task.tsx file.

interface TaskProp {
  title: string;
}

Then, add it as the first generic parameter in the component definition. This is how we tell the TypeScript compiler to always check the Task component adheres to its definition.

class Task extends React.Component<TaskProp> {
  render() {
    return <div>Buy groceries </div>;
  }
}

As soon as we add this, the compiler complains Property 'title' is missing in type. This is where TypeScript helps us in reducing the surprise bugs. It is asking us to provide title prop along with the Task component in the App.tsx file. To do this, we will go to App.tsx file and include title prop in that

function App() {
  return (
    <div className="App">
      <Task title="Pay rent" />
    </div>
  );
}

Now, let's actually render this title prop, instead of hard-coded string in Task.tsx. Switch to Task.tsx file and update our earlier TaskProp.

class Task extends React.Component<TaskProp> {
  render() {
    return <div>{this.props.title}</div>;
  }
}

Let's save the file. And visit localhost:5173. Now we can see the title being rendered, which is actually passed as a prop, i.e., Pay rent.

Now, let's create another component TaskList.tsx, which will hold all the task entries and then render each item using the Task component. To do this, we will create a new file TaskList.tsx under the src folder with the following code:

import React from "react";
import Task from "./Task";

class TaskList extends React.Component {}

export default TaskList;

Now, let's import the Task component and use it to render a task. Let's cut the line from App.tsx and paste it in TaskList.tsx.

class TaskList extends React.Component {
  render() {
    return <Task title="Pay rent" />;
  }
}

Then we will update App.tsx to use the TaskList component.

import TaskList from "./TaskList";

function App() {
  return (
    <div className="App">
      <TaskList />
    </div>
  );
}

Everything is working like before.

Next, we will look at how we can use state in class-based components to display a list of tasks.

To do that, we will have to first create types for props and state for the TaskList component. Add the following code to the TaskList.tsx file.

interface Props {}

interface TaskItem {
  title: string;
}
interface State {
  tasks: TaskItem[];
}

The state will have a key tasks which would be an array of TaskItem.

Let's now initialize a state in the constructor of TaskList component. When we write a constructor, we will have to call the super and pass the props. Also, TypeScript will complain if we don't set the type of props in the constructor.

class TaskList extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = {
      tasks: [],
    };
  }
  render() {
    return <Task title="Pay rent" />;
  }
}

Now, rather than rendering a hardcoded value, let's render the tasks from state. To do that, let's add some initial value to the state.

class TaskList extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = {
      tasks: [{ title: "Pay rent" }, { title: "Submit assignment" }],
    };
  }
  render() {
    <Task title="Pay rent" />;
  }
}

Now, let's use map and loop over the state and render tasks. The final code will look like this:

class TaskList extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props);
    this.state = {
      tasks: [{ title: "Pay rent" }, { title: "Submit assignment" }],
    };
  }
  render() {
    return (
      <>
        {this.state.tasks.map((task) => (
          <Task title={task.title} />
        ))}
      </>
    );
  }
}

Save the file and visit localhost:5173. You can see, the tasks got rendered correctly.