具有相同 ID 的多个按钮的 Onclick 功能?

时间:2021-07-20 13:40:56

标签: javascript reactjs next.js

我有一个用按钮加载一些数据的组件。我有一个函数,它通过 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>
  );
}

1 个答案:

答案 0 :(得分:1)

拥有类似的东西会容易得多:

<button value={stats.player} onClick={() => handleClick(stats.player)}>
   {stats.player}
</button>

...

const handleClick = (player) => {
   setPlayer(player);
   loadPeople();
}

这样您就不需要 id 来代替 button。不仅如此,您还可以避免对多个元素的相同 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);
};