Step 5

We want to transform the App from a "class component" into a "function component" but preserve its features, including state and lifecycle method.

First, transform the App declaration:

- class App exdents Component {
+ function App() {

Next replace the constructor as shown here:

-  constructor(props) {
-   super(props);
-   this.state = {
-     key: "",
-     location: "",
-     which: "",
-     code: "",
-   };
- }
+ const [state, setState] = useState({
+   key: "",
+   location: "",
+   which: "",
+   code: "",
+ });

The useState is a "Hook." You must import it from the React library.

- import React, { Component } from "react";
+ import React, { useState } from "react";

A Hook is a special function that lets you “hook into” React features! For example, useState is a Hook that enables you to add state to function components.

Notice the useState returns two outputs. First is the (current) state and the other is a function to update the state. I didn't need to call these state and setState. I could have given them any other name!

Next, replace the componentDidMount with another React Hook:

- componentDidMount = () => {
-   document.body.addEventListener("keydown", this.onKeyDown);
- };
+ useEffect(() => {
+   document.body.addEventListener("keydown", onKeyDown);
+ }, []);

Note you must import the useEffect function from the React library:

- import React, { useState } from "react";
+ import React, { useState, useEffect } from "react";

The useEffect Hook lets you perform side effects in function components such as attaching an event listener to the DOM.

Next, update the onKeyDown method to an inner function:

- onKeyDown = (event) => {
+ const onKeyDown = (event) => {
-   this.setState({
+   setState({  
      key: event.key,
      location: event.location,
      which: event.which,
      code: event.code,
    });
  };

Finally, update the render method:

- render() {
-   const { key, location, which, code } = this.state;
+   const { key, location, which, code } = state;

    return (
      <Container className="p-3">
        <Header />
        <Row>
          <Card title={"event.key"} value={key} />
          <Card title={"event.location"} value={location} />
          <Card title={"event.which"} value={which} />
          <Card title={"event.code"} value={code} />
        </Row>
      </Container>
    );
- }

And that's it. Here is App.js as updated:

import React, { useState, useEffect } from "react";
import { Container, Row } from "react-bootstrap";
import Header from "./components/Header";
import Card from "./components/Card";

function App() {
  const [state, setState] = useState({
    key: "",
    location: "",
    which: "",
    code: "",
  });

  useEffect(() => {
    document.body.addEventListener("keydown", onKeyDown);
  }, []);

  const onKeyDown = (event) => {
    setState({
      key: event.key,
      location: event.location,
      which: event.which,
      code: event.code,
    });
  };

  const { key, location, which, code } = state;

  return (
    <Container className="p-3">
      <Header />
      <Row>
        <Card title={"event.key"} value={key} />
        <Card title={"event.location"} value={location} />
        <Card title={"event.which"} value={which} />
        <Card title={"event.code"} value={code} />
      </Row>
    </Container>
  );
}

export default App;

Save the file and rerun the app!