Create pokedex with react hooks 
Tags: react, functional, webpack, javascript
Published: 2020-11-03 22:26:59

Hello, I wrote this guide with the purpose to show how to develop a simple app using react, and configuring webpack and babel by hand. I hope that could be helpful if you are starting to work with this technologies, or if you have plans to use them in the near future.

**Before start**

Before start coding we need to add some software to our computer:

- We'll use npm to manage the app dependencies, so we need to install [nodejs](https://nodejs.org/en/).
- A code editor, you can choose your favorite, but I recommend to use [VS Code](https://code.visualstudio.com).

And that's it, now we will are able to develop the app.


**Let's Start**

The first thing that we need to do is initialize the app, to do this we need to use a terminal and move to the folder where we'll create the app (you can do this with the command `cd [directory]`), once we are on that directory we need to type the following command in the console:

`npm init`

This command will open a prompt to ask you some initial configurations for the app in order to generate the package.json file:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/5l7bxrdd41bvvwaty984.png)

After fill the information and type yes to save, we should be able to open VS code or the code editor that we choose, once we open the folder we need to open the embedded terminal on the editor and continue installing the dependencies from there.

_Install the dependencies_

First we need to install the app dependencies, in this case we gonna use react, react-dom, and axios, so we'll to type in the terminal the following command:

```npm i react react-dom axios```

Then we should proceed to install the development dependencies, this dependencies are only to be able to have a development environment to test the app, add libraries, check errors, and run the app in the local host environment.

For this app, we will use webpack and babel to generate the bundles, so we'll run this command on the console to install them as dev dependencies:

```npm i @babel/core@^7.12.3 babel-loader@^8.1.0 babel-preset-react-app@^7.0.2 css-loader@^5.0.0 html-webpack-plugin@^4.5.0 style-loader@^2.0.0 webpack@^4.44.2 webpack-cli@^3.3.12 webpack-dev-server@^3.11.0 --save-dev```

`* In this case I specify the library version to avoid problems when we  will start configuring webpack and babel`

Once we install all the dependencies the package.json file should look in the following way:

```javascript
{
  "name": "pokeapp",
  "version": "1.0.0",
  "description": "demo app",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server"
  },
  "author": "PHD",
  "license": "ISC",
  "dependencies": {
    "axios": "^0.20.0",
    "react": "^17.0.1",
    "react-dom": "^17.0.1"
  },
  "devDependencies": {
    "@babel/core": "^7.12.3",
    "babel-loader": "^8.1.0",
    "babel-preset-react-app": "^7.0.2",
    "css-loader": "^5.0.0",
    "html-webpack-plugin": "^4.5.0",
    "style-loader": "^2.0.0",
    "webpack": "^4.44.2",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  },
  "babel": {
    "presets": [
      "babel-preset-react-app"
    ]
  }
}
```
`* We added some babel configuration to transpile the react app correctly.` 
```javascript
"babel": {
    "presets": [
      "babel-preset-react-app"
    ]
  }
```
`* Also we add in the scripts section the command a script start the app when we'll finish the first configurations.`
```javascript
"scripts": {
    "start": "webpack-dev-server"
  },
``` 

_Configure webpack_

Now we have our dependencies ready, the following step is to setup webpack, to do this we need to add a webpack.config.js file in the root folder, this step is necessary only to have a better control of what happens when we build the app. 

Webpack expects a list of options to generate the bundles based on that configuration, so we need to export that options in the following way:
```javascript
const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

process.env.NODE_ENV = "development";

module.exports = {
    ... // webpack options goes here
};
```
To correctly setup webpack we need to set the following options on the exports section:

1. mode. This setting is to allow to webpack's built-in optimizations that correspond to each environment (development or production).```javascript 
mode: "development"
```

2. target. In this option we could select if the deployment should be on the server or on the browser, we can do more configurations like have multiple targets but are off the scope of this guide. ```javascript
target: "web"
```

3. devtool. With this option we can control if we generate a source map and which type of source map we would use, the source map allow us to debug easily our compiled code on the browser. ```javascript
devtool: "cheap-module-source-map"
```

4. entry. This setting allow us to define the entry point of the app. ```javascript
entry: "./src/index"
```

5. output. This key indicate to webpack how and where it should output the bundles and assets. ```javascript
output: {
    path: path.resolve(__dirname, "build"),
    publicPath: "/",
    filename: "pokebundle.js",
  }
```

6. devServer. In this guide we would use devServer to develop the app, this option allow us to configure how this server should run in the local host. ```javascript
devServer: {
    open: true,
    stats: "minimal",
    overlay: true,
    historyApiFallback: true,
    disableHostCheck: true,
    headers: { "Access-Control-Allow-Origin": "*" },
    https: false,
  }
```

7. plugins. This key is to configure the webpack plugins, those plugins help us to do extra actions when we bundle the app, in this case we gonna use HtmlWebpackPlugin to serve some html files with the app bundle. ```javascript
plugins: [
    new HtmlWebpackPlugin({
      template: "src/index.html",
    }),
  ]
```

8. module. This option determine how webpack would process the different modules of the app. ```javascript
module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ["babel-loader"],
      },
      {
        test: /(\.css)$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  }
```

The complete webpack.config.js file should looks like the following one:

```javascript
const webpack = require("webpack");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

process.env.NODE_ENV = "development";

module.exports = {
  mode: "development",
  target: "web",
  devtool: "cheap-module-source-map",
  entry: "./src/index",
  output: {
    path: path.resolve(__dirname, "build"),
    publicPath: "/",
    filename: "pokebundle.js",
  },
  devServer: {
    open: true,
    stats: "minimal",
    overlay: true,
    historyApiFallback: true,
    disableHostCheck: true,
    headers: { "Access-Control-Allow-Origin": "*" },
    https: false,
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "src/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: ["babel-loader"],
      },
      {
        test: /(\.css)$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
};
```
**Run the app**

We gonna use a simple folder structure just a `src` main folder and inside other two folders `api` and `components` where we will put all our files:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8j5xpj8ik25ock7hp3os.png)

_Now is time to start coding_

The first file that we need to add is the app main component, to do that go to the `components` folder and create an App.js file, then put inside that file the following code:

```javascript
import React from "react";
function App() {
  return (
    <div className="container">
      Pokedex goes here
    </div>
  );
}

export default App;
```
This react hook returns a simple component that renders a div with some text inside.

To render this component properly we need to add the entry point to the app, to do that go to `src` folder and create a index.js file, then type the following code:

```javascript
import React from "react";
import { render } from "react-dom";
import App from "./components/App";

document.addEventListener("DOMContentLoaded", () => {
  render(<App />, document.getElementById("app"));
});
```

This code is to render the app in an html page, the render function looks for an element with id "app" after the DOM content is loaded, and then try to render our component there.

But we don't have any html page yet, so we need to add an html page in the `src` folder to use it as a template for the app, please create an index.html file and put the following content there:

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Pokedex</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
      integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
      crossorigin="anonymous"
    />
    <script
      src="https://code.jquery.com/jquery-3.5.1.slim.min.js"
      integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
      integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
      crossorigin="anonymous"
    ></script>
  </head>

  <body>
    <div id="app"></div>
  </body>
</html>
```

Notice how we added some style sheets to the html head, we did that to use [Bootstrap](https://getbootstrap.com) in the app.

Now we are ready to run the app, just go to the console and type `npm start` this command should bundle the app and open the default browser with the running application.

_Get Pokemon information_

To get the Pokemon information we gonna use [the Pokemon API](https://pokeapi.co/) this APIs provide some endpoints that we could use to get all the information that we need for the app, but first we need to create some files to connect the app to any REST API.

Add the following files to the `api` folder ApiService.js and ApiUtils.js, then put the following code in the ApiService.js file:

```javascript
import axios from "axios"; // this library is to fetch data from REST APIs
import { handleError, handleResponse } from "./ApiUtils";

const httpRequest = (method, url, request, headers) => {
  // return a promise
  return axios({
    method,
    url,
    data: request,
    headers,
  })
    .then((res) => {
      const result = handleResponse(res);
      return Promise.resolve(result);
    })
    .catch((err) => {
      return Promise.reject(handleError(err));
    });
};

const get = (url, request, headers) => {
  let queryString = "";
  if (request && Object.keys(request).length > 0) {
    queryString += "?";
    let len = Object.keys(request).length,
      cnt = 0;
    
    // transform the request object in a query string
    for (let key in request) {
      cnt++;
      queryString += `${key}=${request[key].toString()}`;
      if (len > cnt) queryString += "&";
    }
  }
  return httpRequest("get", `${url}${queryString}`, request, headers);
};

const deleteRequest = (url, request, headers) => {
  return httpRequest("delete", url, request, headers);
};

const post = (url, request, headers) => {
  return httpRequest("post", url, request, headers);
};

const put = (url, request, headers) => {
  return httpRequest("put", url, request, headers);
};

const patch = (url, request, headers) => {
  return httpRequest("patch", url, request, headers);
};

const Api = {
  get,
  delete: deleteRequest,
  post,
  put,
  patch,
};

export default Api;
```

In this file we use `axios` to do the REST requests, we handle the responses with other two functions `handleResponse` and `handleError` those methods are imported from the ApiUtils.js file, also we add some logic to the `get` method to have a consistent way to do any REST request, at the end of the file we export all the methods inside an Api object. 

For the ApiUtils.js file we need to write the following code, to handle appropriately the server responses:
```javascript
export function handleResponse(response) {
    if (
      response.status === 200 ||
      response.status === 202 ||
      response.statusText === "OK" ||
      response.statusText === "Created"
    )
      return response.data;
    if (response.status === 400) {
      // So, a server-side validation error occurred.
      // Server side validation returns a string error message, so parse as text instead of json.
      const error = response.statusText();
      throw new Error(error);
    }
    throw new Error("Network response was not ok.");
  }
  
  // In a real app, would likely call an error logging service.
  export function handleError(error) {
    console.error("API call failed. " + error);
    throw error;
  }
  ```

Now is time to connect the app to the Pokemon API, we need to create a PokemonService.js file inside of `api` folder, in this file we would add all the methods to get the Pokemon information.

First we need to import the api dependencies into the service:
```javascript
import ApiService from "./ApiService";
```

Then we could define the three async methods that we'll use:

1. getKantoPokemon. This method will get a list with all kanto Pokemon, with this list we'll be able to get more data for all the pokemons.```javascript
export const getKantoPokemon = async () => {
  try {
    let response = await ApiService.get(`https://pokeapi.co/api/v2/pokemon`, {
      limit: 151,
    });
    return response.results;
  } catch (err) {
    throw err;
  }
};
```

2. getPokemonData. This method is to get the Pokemon details, this method require an URL to get the Pokemon information. ```javascript
export const getPokemonData = async (url) => {
  try {
    let response = await ApiService.get(url);
    return response;
  } catch (err) {
    throw err;
  }
};
```

3. getPokemonKantoData. This method use the first two methods, the first one to get all kanto Pokemon and the second one to get the details of all the pokemons on the response of the first call. ```javascript
export const getPokemonKantoData = async () => {
  try {
    //get pokemon list
    let pokemons = await getKantoPokemon();

    //get promises to obtain data for all pokemon in the list
    let pokemonPromises = pokemons.map((p) => getPokemonData(p.url));
    
    //return all the pokemon data
    return await Promise.all(pokemonPromises);
  } catch (err) {
    throw err;
  }
};
```

The complete code of this file is the following:

```javascript
import ApiService from "./ApiService";

export const getKantoPokemon = async () => {
  try {
    let response = await ApiService.get(`https://pokeapi.co/api/v2/pokemon`, {
      limit: 151,
    });
    return response.results;
  } catch (err) {
    throw err;
  }
};

export const getPokemonData = async (url) => {
  try {
    let response = await ApiService.get(url);
    return response;
  } catch (err) {
    throw err;
  }
};

export const getPokemonKantoData = async () => {
  try {
    //get pokemon list
    let pokemons = await getKantoPokemon();

    //get promises to obtain data for all pokemon in the list
    let pokemonPromises = pokemons.map((p) => getPokemonData(p.url));
    
    //return all the pokemon data
    return await Promise.all(pokemonPromises);
  } catch (err) {
    throw err;
  }
};
```

**Create the Pokedex components**

We'll use three components, we need to create the `home` folder inside of `components` and then proceed to create the following files:

1. HomeContainer.js this component will act as our container.

2. PokemonList.js this component will display all the list of Pokemons.

3. PokemonDetail.js in this component we will display the Pokemon details once the user click on one element of the list.

Also we need to add some css styles, so to handle those styles in one file we need to create the `pokemon.css` file in the `src` folder.

_PokemonList component_

In this functional component we need to receive the Pokemon list, and which is the selected Pokemon as props, the first prop is to display all Pokemons in a friendly way, and the second one is to be able to highlight the selected Pokemon.

First we need to do the imports that we'll use:
```javascript
import React from "react";
import "../../pokemon.css";
```

Then we need to create the functional component:

```javascript
function PokemonList({ pokemons, selectPokemon }) {
    ... // draw Pokemon function goes here
    ... // return goes here
};
```
If the `pokemons` array prop have records we'll return an `<li>` item for each object in the array, in this tag we can properly render the items to display them in a friendly way:

```javascript
  const drawPokemon = () => {
    return pokemons.map((p, id) => (
      <li
        key={id}
        onClick={() => selectPokemon(p.id)}
        className={
          p.selected
            ? "list-group-item d-flex pokemon-item-list selected"
            : "list-group-item d-flex pokemon-item-list"
        }
      >
        <img className="col-3" src={p.sprites.front_default} />
        <p className="col-4 pokemon-text-list">N.º {p.id}</p>
        <p className="col-5 pokemon-text-list">{p.name}</p>
      </li>
    ));
  };
```

In the return of the component, we need to check if the `pokemons` prop length is greater than 0, because we'll get the data from the server, and when the component is rendered at the screen this prop will not have data:

```javascript
return <ul className="list-group">{pokemons.length > 0 && drawPokemon()}</ul>;
```

And finally don't forget to export the component to be able to use it:
```javascript
export default PokemonList;
```

The complete file component should look like the following:

```javascript
import React from "react";
import "../../pokemon.css";

function PokemonList({ pokemons, selectPokemon }) {
  const drawPokemon = () => {
    return pokemons.map((p, id) => (
      <li
        key={id}
        onClick={() => selectPokemon(p.id)}
        className={
          p.selected
            ? "list-group-item d-flex pokemon-item-list selected" // the selected class is to highlight the Pokemon selected
            : "list-group-item d-flex pokemon-item-list"
        }
      >
        <img className="col-3" src={p.sprites.front_default} />
        <p className="col-4 pokemon-text-list">N.º {p.id}</p>
        <p className="col-5 pokemon-text-list">{p.name}</p>
      </li>
    ));
  };

  return <ul className="list-group">{pokemons.length > 0 && drawPokemon()}</ul>;
}

export default PokemonList;
```

_PokemonDetail component_

This functional component will render the details of the selected Pokemon, the name, a picture, the Pokemon types, etc.

First we need to import the libraries that we'll use:
```javascript
import React from "react";
```

Then we need to create the component body:
```javascript
function PokemonDetail({ pokemon }) {
    ... // getTypeStyleFunction goes here
    ... // return goes here
}
```
In this component we use the getTypeStyle function, this function is to used to get some css styles that rely on the Pokemon type:

```javascript
const getTypeStyle = (type) => {
    let backgroundColor = "";
    switch (type) {
      case "grass":
        backgroundColor = "#9bcc50";
        break;
      case "poison":
        backgroundColor = "#b97fc9";
        break;
      case "fire":
        backgroundColor = "#fd7d24";
        break;
      case "flying":
        backgroundColor = "#3dc7ef";
        break;
      case "water":
        backgroundColor = "#4592c4";
        break;
      case "bug":
        backgroundColor = "#729f3f";
        break;
      case "normal":
        backgroundColor = "#a4acaf";
        break;
      case "electric":
        backgroundColor = "#eed535";
        break;
      case "ground":
        backgroundColor = "#ab9842";
        break;
      case "fairy":
        backgroundColor = "#fdb9e9";
        break;
      case "fighting":
        backgroundColor = "#d56723";
        break;
      case "psychic":
        backgroundColor = "#f366b9";
        break;
      case "rock":
        backgroundColor = "#a38c21";
        break;
      case "steel":
        backgroundColor = "#9eb7b8";
        break;
      case "ghost":
        backgroundColor = "#7b62a3";
        break;
      case "ice":
        backgroundColor = "#51c4e7";
      case "dragon":
        backgroundColor = "#f16e57";

      default:
        backgroundColor = "#000";
        break;
    }
    return { backgroundColor, color: "#FFF", margin: "5px" };
  };
```

Then in the return we render some html to display the Pokemon selected in a friendly way:

```javascript
return (
    <div className="pokemon-image-container">
      <h1 className="text-center">
        N.º {pokemon.id} {pokemon.name}
      </h1>
      <img
        src={`https://pokeres.bastionbot.org/images/pokemon/${pokemon.id}.png`}
        className="img-fluid pokemon-image-detail d-block mx-auto"
      />
      <div className="pokemon-box-details">
        <ul className="list-group list-group-horizontal justify-content-center">
          {pokemon.types.length > 0 &&
            pokemon.types.map((t, idx) => (
              <li
                key={idx}
                className="list-group-item d-flex pokemon-list-details"
                style={getTypeStyle(t.type.name)}
              >
                {t.type.name}
              </li>
            ))}
        </ul>
      </div>
    </div>
  );
```

Finally don't forget to export the component:
```javascript
export default PokemonDetail;
```

The complete file component should look like the following:

```javascript
import React from "react";

function PokemonDetail({ pokemon }) {
  const getTypeStyle = (type) => {
    let backgroundColor = "";
    switch (type) {
      case "grass":
        backgroundColor = "#9bcc50";
        break;
      case "poison":
        backgroundColor = "#b97fc9";
        break;
      case "fire":
        backgroundColor = "#fd7d24";
        break;
      case "flying":
        backgroundColor = "#3dc7ef";
        break;
      case "water":
        backgroundColor = "#4592c4";
        break;
      case "bug":
        backgroundColor = "#729f3f";
        break;
      case "normal":
        backgroundColor = "#a4acaf";
        break;
      case "electric":
        backgroundColor = "#eed535";
        break;
      case "ground":
        backgroundColor = "#ab9842";
        break;
      case "fairy":
        backgroundColor = "#fdb9e9";
        break;
      case "fighting":
        backgroundColor = "#d56723";
        break;
      case "psychic":
        backgroundColor = "#f366b9";
        break;
      case "rock":
        backgroundColor = "#a38c21";
        break;
      case "steel":
        backgroundColor = "#9eb7b8";
        break;
      case "ghost":
        backgroundColor = "#7b62a3";
        break;
      case "ice":
        backgroundColor = "#51c4e7";
      case "dragon":
        backgroundColor = "#f16e57";

      default:
        backgroundColor = "#000";
        break;
    }
    return { backgroundColor, color: "#FFF", margin: "5px" };
  };

  return (
    <div className="pokemon-image-container">
      <h1 className="text-center">
        N.º {pokemon.id} {pokemon.name}
      </h1>
      <img
        src={`https://pokeres.bastionbot.org/images/pokemon/${pokemon.id}.png`}
        className="img-fluid pokemon-image-detail d-block mx-auto"
      />
      <div className="pokemon-box-details">
        <ul className="list-group list-group-horizontal justify-content-center">
          {pokemon.types.length > 0 &&
            pokemon.types.map((t, idx) => (
              <li
                key={idx}
                className="list-group-item d-flex pokemon-list-details"
                style={getTypeStyle(t.type.name)}
              >
                {t.type.name}
              </li>
            ))}
        </ul>
      </div>
    </div>
  );
}

export default PokemonDetail;
```

_HomeContainer component_

This functional component act as a container, so in this component we we'll import the other two components, we gonna get access to the APIs, and also we'll use some hooks like useEffect to get the Pokemon list when the screen loads, useState to handle the state of the component, and send that state as props to the child components.

First we need to import the libraries and components that we'll use:
```javascript
import React, { useEffect, useState } from "react";
import PokemonList from "./PokemonList";
import PokemonDetail from "./PokemonDetail";
import { getPokemonKantoData } from "../../api/PokemonService";
```

Then we need to create the component body:
```javascript
function HomeContainer() {
    ...// state declarations goes here
    ...// use effect goes here
    ...// functions goes here
    ...// return goes here
}
```

The states that we need to use will be the following

- pokeList. To handle the complete list of pokemons.
- filteredPokeList. To handle the list of pokemons filtered.
- filter. To set which pokemons we will filter.
- pokemonSelected. To handle the Pokemon selected.

```javascript
  const [pokeList, setPokeList] = useState([]);
  const [filteredPokeList, setFilteredPokeList] = useState([]);
  const [filter, setFilter] = useState("");
  const [pokemonSelected, setPokemonSelected] = useState(null);
```

Then we need to get the Pokemon list when the app loads, to do this action we need to use the useEffect hook, to call the API that gets the information:
```javascript
  useEffect(async () => {
    try {
      let pokemons = await getPokemonKantoData();
      setFilteredPokeList(pokemons);
      setPokeList(pokemons);
    } catch (err) {
      alert("an error occurs");
      console.error(err);
    }
  }, []);
```

To have the filter functionality we can use a function to set the state `filteredPokeList` based on the received value:
```javascript
  const filterPokemon = (value) => {
    setFilter(value); // set the filter value
    setFilteredPokeList(
      pokeList.filter((p) => p.name.toLowerCase().includes(value.toLowerCase()))
    ); // set the pokemons that match with the value
  };
```

To highlight the selected Pokemon, and also to display the Pokemon details, we need to create a function that sets the `pokemonSelected` state:
```javascript
  const handleSelect = (pokemonId) => {
    setPokemonSelected(pokeList.filter((p) => p.id === pokemonId)[0]); // set the selected Pokemon to display the details
    setFilteredPokeList(
      filteredPokeList.map((p) =>
        p.id === pokemonId
          ? { ...p, selected: true }
          : { ...p, selected: false }
      )
    ); // filter the list of pokemons to display
  };
```

Finally, we need to return the container structure to display the app:
```javascript
return (
    <div className="row pokemon-app-container">
      <div className="col-6">
        {pokemonSelected && <PokemonDetail pokemon={pokemonSelected} />}
      </div>
      <div className="col-6 pokemon-list-container">
        <div style={{ height: "10%" }}>
          <div className="form-group">
            <label>Search</label>
            <input
              type="text"
              className="form-control"
              placeholder="Type to search a pokemon..."
              value={filter}
              onChange={(event) => {
                let { value } = event.target;
                filterPokemon(value);
              }}
            />
          </div>
        </div>
        <div style={{ height: "90%", overflowY: "auto" }}>
          <PokemonList
            pokemons={filteredPokeList}
            selectPokemon={handleSelect}
          />
        </div>
      </div>
    </div>
  );
```

Finally export the component to be able to use it:
```javascript
export default HomeContainer;
```

The complete code of this component should look like the following:

```javascript
import React, { useEffect, useState } from "react";
import PokemonList from "./PokemonList";
import PokemonDetail from "./PokemonDetail";
import { getPokemonKantoData } from "../../api/PokemonService";

function HomeContainer() {
  useEffect(async () => {
    try {
      let pokemons = await getPokemonKantoData();
      console.log(pokemons);
      setFilteredPokeList(pokemons);
      setPokeList(pokemons);
    } catch (err) {
      alert("an error occurs");
      console.error(err);
    }
  }, []);

  const [pokeList, setPokeList] = useState([]);
  const [filteredPokeList, setFilteredPokeList] = useState([]);
  const [pokemonSelected, setPokemonSelected] = useState(null);
  const [filter, setFilter] = useState("");

  const handleSelect = (pokemonId) => {
    setPokemonSelected(pokeList.filter((p) => p.id === pokemonId)[0]);
    setFilteredPokeList(
      filteredPokeList.map((p) =>
        p.id === pokemonId
          ? { ...p, selected: true }
          : { ...p, selected: false }
      )
    );
  };

  const filterPokemon = (value) => {
    setFilter(value);
    setFilteredPokeList(
      pokeList.filter((p) => p.name.toLowerCase().includes(value.toLowerCase()))
    );
  };
  return (
    <div className="row pokemon-app-container">
      <div className="col-6">
        {pokemonSelected && <PokemonDetail pokemon={pokemonSelected} />}
      </div>
      <div className="col-6 pokemon-list-container">
        <div style={{ height: "10%" }}>
          <div className="form-group">
            <label>Search</label>
            <input
              type="text"
              className="form-control"
              placeholder="Type to search a pokemon..."
              value={filter}
              onChange={(event) => {
                let { value } = event.target;
                filterPokemon(value);
              }}
            />
          </div>
        </div>
        <div style={{ height: "90%", overflowY: "auto" }}>
          <PokemonList
            pokemons={filteredPokeList}
            selectPokemon={handleSelect}
          />
        </div>
      </div>
    </div>
  );
}

export default HomeContainer;
```

_The Pokemon css stylesheet_

I don't want to go deep in the css because I think is out of the scope of this guide, so I only add the style sheet here:

```css
.pokemon-item-list {
  border-radius: 40px !important;
  margin-top: 10px;
  margin-bottom: 10px;
  border-width: 0px;
}

.pokemon-item-list.selected {
  background-color: #e3350d;
  color: white;
  border-width: 1px;
}

.pokemon-item-list:hover {
  border-width: 1px;
  background-color: #E2E2E2;
  color: white;
}

.pokemon-text-list {
  font-size: 24px;
  margin-top: 20px;
}

.pokemon-app-container {
  height: 100vh;
}

.pokemon-list-container {
  height: 100%;
  overflow-y: auto;
}

.pokemon-image-container {
  margin-top: 4rem;
  border: 1px solid #F2F2F2;
  background-color: #F2F2F2;
  border-radius: 20px;
  padding: 10px;
}

.pokemon-image-detail {
  height: 400px;
}

.pokemon-list-details {
  margin-top: 20px;
  border-width: 0px;
}

.pokemon-box-details {
  margin-top: 10px;
}
```

**Ending the app**

Finally we need to update our `App.js` file this to load the components that we created:
```javascript
import React from "react";
import Home from "./Home/HomeContainer"; // import the container component

// return the Home component
function App() {
  return (
    <div className="container">
      <Home /> 
    </div>
  );
}

export default App;
```

With this the app should be completed, but we can improve many parts of them, like add proptypes, use redux, refactor the code in some parts, optimize the bundles, etc.

You can get the complete code in the following repository [PokeApp](https://github.com/elPesecillo/pokeApp)

If you are here, I want to say you thank you so much for read this guide, and if you have any comment I really appreciate your feedback.