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!