[英]How to make filter with Radio Input
我实际上正在学习 Javascript 和 React,但我遇到了问题。 我正在尝试构建 Pokedex,但我遇到了问题。
我放了一些无线电输入来制作世代过滤器(口袋妖怪),但我不知道如何将我的输入与 API 上的 apiGeneration 编号链接起来......
我还想按名称创建一个搜索栏,我可以在 console.log() 上看到 searchBar.value,但我不能在 searchBar 元素上放置一个 addeventlistener ...
非常感谢你的帮助。 ^^ API 链接: https://pokebuildapi.fr/api/v1/pokemon
import axios from "axios";
import React, { useEffect, useState } from "react";
import Card from "./Card";
const Pokedex = () => {
const [data, setData] = useState([]);
const radios = ["1G", "2G", "3G", "4G", "5G", "6G", "7G", "8G"];
const [selectedRadio, setSelectedRadio] = useState("");
useEffect(() => {
axios
.get("https://pokebuildapi.fr/api/v1/pokemon")
.then((res) => setData(res.data));
}, []);
return (
<div className="pokemons">
<h2 id="search-title">Pokedex</h2>
<p className="search-text">Recherhe par nom</p>
<div>
<input type="search" id="search-bar"></input>
</div>
<div className="gen-search">
{radios.map((generation) => (
<ul className="radio-container">
<li>
<input
type="radio"
id={generation}
name="generationRadio"
checked={generation === selectedRadio}
onChange={(e) => setSelectedRadio(e.target.id)}
/>
<label htmlFor={generation}>{generation}</label>
</li>
</ul>
))}
</div>
{selectedRadio && (
<button onClick={() => setSelectedRadio("")}>
Annuler la recherche
</button>
)}
<div className="pokemon-container">
<ul>
{data
.filter((pokemon) => {
/* ... */
})
.map((pokemon, index) => (
<Card key={index} pokemon={pokemon} />
))}
</ul>
</div>
</div>
);
};
export default Pokedex;
API
// 20230130034321
// https://pokebuildapi.fr/api/v1/pokemon
[
{
"id": 1,
"pokedexId": 1,
"name": "Bulbizarre",
"image": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/1.png",
"sprite": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png",
"slug": "Bulbizarre",
"stats": {
"HP": 45,
"attack": 49,
"defense": 49,
"special_attack": 65,
"special_defense": 65,
"speed": 45
},
"apiTypes": [
{
"name": "Poison",
"image": "https://static.wikia.nocookie.net/pokemongo/images/0/05/Poison.png"
},
{
"name": "Plante",
"image": "https://static.wikia.nocookie.net/pokemongo/images/c/c5/Grass.png"
}
],
"apiGeneration": 1,
这是一个基于您的代码段的示例。
变化:
useEffect
以确保所选生成始终有效。filter()
以将显示限制为选定的世代。key
以使用pokemon.id
,这是一个更好的值,因为如果您在任何时间点重新排序或更改列表,它将需要做出更少的工作。import axios from "axios";
import React, { useEffect, useState, useMemo } from "react";
import Card from "./Card";
const Pokedex = () => {
const [data, setData] = useState([]);
// Get a list of generations from the data retrieved from the all pokemon api.
const generations = useMemo(() => {
// if data not yet loaded, return empty array (no generations).
if (!data) {
return [];
}
// get a list of all unique generations:
// - use list.map() to get the apiGeneration property of each pokemon.
// - use new Set(list) to restrict the list to only unique values.
// - use [...list] to change the Set back into an array.
const allGenerations = [...new Set(data.map(x => x.apiGeneration))];
// sort the list
allGenerations.sort();
// return the list of all generations.
return allGenerations;
}, [data])
// state value to store the currently selected generation.
const [selectedGeneration, setSelectedGeneration] = useState(undefined);
// When ever the list of generations changes (should only be on reload of
// pokemon data) ensure that the selected generation still exists, otherwise
// set it back to all generations (undefined).
useEffect(() => {
setSelectedGeneration(c => {
if (!!c && !generations.includes(c)) {
return undefined;
}
return c;
});
}, [generations, setSelectedGeneration])
// load pokemon data.
useEffect(() => {
axios
.get("https://pokebuildapi.fr/api/v1/pokemon")
.then((res) => setData(res.data));
}, []);
return (
<div className="pokemons">
<h2 id="search-title">Pokedex</h2>
<p className="search-text">Recherhe par nom</p>
<div>
<input type="search" id="search-bar"></input>
</div>
<div className="gen-search">
{
// loop through generations and create radio buttons
generations?.map((generation) => (
<ul className="radio-container">
<li>
<input
type="radio"
id={`generation-${generation}`}
name="generationRadio"
checked={generation === selectedGeneration}
onChange={(e) => setSelectedGeneration(generation)}
/>
<label htmlFor={`generation-${generation}`}>G{generation}</label>
</li>
</ul>
))
}
</div>
{
// create button to clear generation filter.
selectedGeneration && (
<button onClick={() => setSelectedGeneration(undefined)}>
Annuler la recherche
</button>
)
}
<div className="pokemon-container">
<ul>
{
// filter and map out pokemon.
data
.filter((pokemon) => {
// if no filter, return all pokemon.
if (!selectedGeneration) {
return true;
}
// ensure pokemon matches selected generation.
return pokemon.apiGeneration === selectedGeneration;
})
.map((pokemon, index) => (
<Card key={pokemon.id} pokemon={pokemon} />
))
}
</ul>
</div>
</div>
);
};
export default Pokedex;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.