同一ID的多个按钮的点击功能



我有一个组件,它用按钮加载一些数据。我有一个函数,它通过ID获取按钮,并将状态/变量更新为该按钮值,然后基于该值加载数据。然而,由于所有按钮ID都是相同的,它只适用于第一个按钮。。。

我不知道如何为每个按钮设置唯一的ID,因为它们是通过map((函数生成的,即使我知道,我也不确定我的函数如何在不为每个按钮编写函数的情况下针对每个按钮。。。

编辑:我现在已经为按钮设置了唯一ID,还需要解决其他问题。

return member.map((player, index) => (
<>
{" "}
<React.Fragment key={index}>
<br />{" "}
<div>
<br />
{player.map((stats) => (
<React.Fragment key={stats.player}>
<div class="flex-child">
<button id={'btn' + index} value={stats.player}>
{stats.player}
</button>
<p>{stats.role}</p>
<p>{stats.win_rate}</p>
<p>{stats.matches}</p>
<p>{stats.total_battles} Total Battles</p>
<p>{stats.score} / Points Earned</p>
</div>
</React.Fragment>
))}
</div>
<br />
</React.Fragment>
</>
));
};
export default SquadMembers;

这是index.js

import Head from "next/head";
import React, { useState } from "react";
import Teams from "../components/Teams";
import styles from "../../styles/Home.module.css";
import SquadMembers from "../components/SquadMembers";
import SquadData from "../components/SquadData";
export default function Home() {
const [teams, setTeams] = useState([]);
const [squads, setSquads] = useState([]);
const [player, setPlayer] = useState("Player Name");
const [squad, setSquad] = useState("default");
const [loading, setLoading] = useState(false);
function clicky() {
if (!document.getElementById("btn")) {
} else {
setPlayer(document.getElementById("btn").value);
loadPeople();
}
}
if (typeof window === "object") {
if (!document.getElementById("btn")) {
} else {
document.getElementById("btn").onclick = function () {
clicky();
};
}
}
function handleChange(e) {
setSquad(e.target.value);
}
const loadPeople = async () => {
setLoading(true);
const req = await fetch(`/api/player/${player}`);
const json = await req.json();
setTeams(json);
setLoading(false);
};
const loadSquad = async () => {
setLoading(true);
const req = await fetch(`/api/squad/${squad}`);
const json = await req.json();
setSquads(json);
setLoading(false);
setTeams([]);
};
return (
<div className={styles.main}>
<main className={styles.main}>
<h1>Silph Team Finder</h1>
<br />
<div>
<select value={squad} onChange={handleChange}>
<option value="default" selected disabled hidden>
Choose here
</option>
<option value="a342">Lots of options, cut them to save space</option>
</select>
<button onClick={() => loadSquad()}>Load</button>
<input
value={player}
id="player"
onChange={(e) => setPlayer(e.target.value)}
/>
<button onClick={() => loadPeople()} id="pbtn">
Load
</button>
{loading && <div className={styles.load}>LOADING</div>}
</div>
<div className={styles.teams}>
<SquadData squadz={squads} />
<Teams teams={teams} />
<div class="player-container">
<SquadMembers squadz={squads} />
</div>
</div>
</main>
</div>
);
}

拥有这样的东西会容易得多:

<button value={stats.player} onClick={() => handleClick(stats.player)}>
{stats.player}
</button>
...
const handleClick = (player) => {
setPlayer(player);
loadPeople();
}

这样一来,button就不需要id了。不仅如此,您还可以避免对多个元素的同一id发出警告。

那么我想谈谈loadPeople()。如果我在这个函数中理解正确,那么您使用的是player,它将由setPlayer设置。这不是一个好办法。setPlayer是异步的,您可以采用player的旧值。最好将最后一个player值直接传递给loadPeople函数。类似于:

const handleClick = (player) => {
setPlayer(player);
loadPeople(player);
}
const loadPeople = async (newPlayer) => {
setLoading(true);
const req = await fetch(`/api/player/${newPlayer}`);
const json = await req.json();
setTeams(json);
setLoading(false);
};

最新更新