How to return a list according to selected item?

Viewed 40

I'm still a beginner in ReactJS and I'm creating a project that works with a list of pokemons. The user selects a type of pokemon, and then I must return a list according to the user's selection.

I have a list with all pokemons, but some pokemons can belong to more than one type, as shown in this example below:

enter image description here

enter image description here

Could you tell me how to create a list with only the type of pokemon that the user selected? I think I can do this using reducer(), but I have no idea how to do it.

Here's my code I put into codesandbox

import React from "react";
import { useHistory } from "react-router-dom";
import { Button } from "@material-ui/core";

import { types } from "./data";

import "./styles.css";

const App = () => {
  const history = useHistory();
  const handleType = (type) => {
    history.push({
      pathname: "/list",
      state: type
    });
  };

  return (
    <div className="content">
      <h3>Pokémon Types</h3>
      {types.results.map((type) => (
        <Button
          key={type.name}
          style={{
            margin: "5px"
          }}
          variant="contained"
          onClick={() => handleType(type.name)}
        >
          {type.name}
        </Button>
      ))}
    </div>
  );
};

export default App;

import React from "react";
import { useLocation } from "react-router-dom";

import { pokemons } from "../data";

const List = () => {
  const { state } = useLocation();

  console.log("state: ", state);
  console.log(pokemons);

  return <div>List</div>;
};

export default List;

Thank you in advance for any help.

1 Answers

You have a lot of ways to do that, but since you are still learning and you got a nice shot of code, I will introduce useMemo for you:

you can add useMemo to memorize and process data, then get the result direct...

look at this example:

  const pk = useMemo(() => {
    if (!state) return "State Empty!";

    let result = [];
    pokemons.forEach((v, i) => {
      if (v.type.includes(state)) {
        result.push(<li key={v.name + i}>{v.name}</li>);
      }
    });

    return result;
  }, [pokemons, state]);

  return <ul>{pk}</ul>;

By this code, I got your list, check details in a simple loop, and then retrieve the needed list...

Notes:

  1. In key I set name and i, but it's not totally correct, but it seems there is duplication on data, and why its not totally correct?, since we need to make sure to prevent re-render when no real change, but index if order change that's mean re-render...
  2. You can use anyway like reducer, filter, or create a separate component and put it nested of useMemo
  3. You can enhance data style to can check or retrieve data fast by Hash table...

Demo

Related