我一直在做一个可以用来存储集合的Web应用程序,有一个仪表板页面,用户可以看到的所有集合都显示在一个表格中,其中每一行都是一个集合,列用于显示集合名称和一个删除按钮.

这是集合体Row.tsx文件:

"use client";

import React from "react";
import { useSession } from "next-auth/react";

type TableRow = {
  id: string;
  name: string;
};

type Props = {
  row: TableRow;
  className?: string;
};

const DEFAULT_ROW: TableRow = {
  id: "0",
  name: "Collection",
};

const CollectionRow = ({ row = DEFAULT_ROW, className }: Props) => {


  const handleDeleteCollection = async () => {
    console.log(row.id);
  };

  return (
    <tr key={row.id}>
      <td className={className}>
        <div className="flex flex-col">
          <p className="text-sm">{row.name}</p>
        </div>
      </td>
      <td className={className}>
        <button
          onClick={() => (document.getElementById("delete") as any).showModal()}
          className="btn btn-primary btn-sm"
        >
        </button>
        <dialog id="delete" className="modal">
          <div className="modal-box">
            <h3 className="font-bold text-lg">Delete Collection?</h3>
            <div className="modal-action">
              <form method="dialog">
                <button className="btn btn-primary">Close</button>
              </form>
              <button onClick={handleDeleteCollection}>
                Delete
              </button>
            </div>
          </div>
        </dialog>
      </td>
    </tr>
  );
};

export default CollectionRow;

下面是使用该组件的Page.tsx:

import React from "react";

import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth_options";
import CollectionRow from "@/components/collectionRow";
import AddCollection from "@/components/addCollection";

const TABLE_HEAD = [
  "Name",
  "Delete",
];

type TableRow = {
  id: string;
  name: string;
};

export default async function page() {
  
  // Api request to fetch all rows

  const tableRows: TableRow[] = (await res.json()) || [];

  return (
    <div>
      <div className="h-full w-full bg-base-200">
        <div className="px-0 overflow-auto ">
          <table className="mt-2 w-full min-w-max table-auto text-left">
            <thead>
              <tr>
                {TABLE_HEAD.map((head, index) => (
                  <th
                    key={head}
                    className="cursor-pointer border-y border-primary p-4"
                  >
                    <p className="text-sm flex items-center justify-between gap-2">
                      {head} {index !== TABLE_HEAD.length - 1}
                    </p>
                  </th>
                ))}
              </tr>
            </thead>
            <tbody>
              {tableRows.map((row: TableRow, index) => {
                const isLast = index === tableRows.length - 1;
                const classes = isLast ? "p-4" : "p-4 border-b border-primary ";

                return (
                  <CollectionRow key={index} row={row} className={classes} />
                );
              })}
            </tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

我的问题是,在handleDeleteCollection中,我记录row.id,但是出于某种原因,无论按钮来自哪一行,我得到的id总是第一行的那一行.我想使用该ID删除该行,但我就是无法获得它.

我试着用这种方式编辑Collection tionRow.tsx:

"use client";

import React from "react";
import { useSession } from "next-auth/react";

type TableRow = {
  id: string;
  name: string;
};

type Props = {
  row: TableRow;
  className?: string;
};

const DEFAULT_ROW: TableRow = {
  id: "0",
  name: "Collection",
};

const CollectionRow = ({ row = DEFAULT_ROW, className }: Props) => {


  const handleDeleteCollection = async (
    e: React.MouseEvent<HTMLButtonElement, MouseEvent>
  ) => {
    console.log(e.target);
  };

  return (
    <tr key={row.id}>
      <td className={className}>
        <div className="flex flex-col">
          <p className="text-sm">{row.name}</p>
        </div>
      </td>
      <td className={className}>
        <button
          onClick={() => (document.getElementById("delete") as any).showModal()}
          className="btn btn-primary btn-sm"
        >
        </button>
        <dialog id="delete" className="modal">
          <div className="modal-box">
            <h3 className="font-bold text-lg">Delete Collection?</h3>
            <div className="modal-action">
              <form method="dialog">
                <button className="btn btn-primary">Close</button>
              </form>
              <button onClick={handleDeleteCollection} id={row.id}>
                Delete
              </button>
            </div>
          </div>
        </dialog>
      </td>
    </tr>
  );
};

export default CollectionRow;

要记录所有按钮信息,包括id,它仍然是第一行的id.

奇怪的是,所有其他信息(我只是为了保持代码整洁才放入名称,但我的代码中还有更多信息)都正确显示,唯一有问题的是id.我也试着在Page.tsx中打印它,但在那里它似乎是正确的.我不知道我做错了什么. 有谁能帮帮我吗?谢谢

推荐答案

发生这种情况是因为您的所有按钮都在调用相同的对话框来打开.

要在代码中解决这个问题,您应该 for each 对话框指定一个不同的ID,并在每次单击按钮打开它时调用正确的ID:

<button
    onClick={() => (document.getElementById(`delete_${row.id}`)).showModal()}
    className="btn btn-primary btn-sm"
>

并将此特定ID指定给您的模式:

<dialog id={`delete_${row.id}`} className="modal">

Javascript相关问答推荐

在类型脚本中使用浏览器特定属性的正确方法是什么?

如何在alpinejs中显示dev中x-for的元素

Mongodb拥有5亿个文档,我想根据JavaScript驱动程序中的两个字段使用regEx进行搜索,而不是模式

设置默认值后动态更新japbox或调色板

如何从对象嵌套数组的第二级对象中过滤出键

Flisk和JS错误:未捕获的Syntax错误:意外的令牌'<'

RxJS setTimeout操作符等效

如何获取转换字节的所有8位?

zoom svg以适应圆

为什么我的includes声明需要整个字符串?

类型脚本中只有字符串或数字键而不是符号键的对象

如何解决CORS政策的问题

类型自定义lazy Promise. all

如何粗体匹配的字母时输入搜索框使用javascript?

显示图—如何在图例项上添加删除线效果?

如何调用名称在字符串中的实例方法?

如何在文本字段中输入变量?

使用getBorbingClientRect()更改绝对元素位置

如果一个字符串前面有点、空格或无字符串,后面有空格、连字符或无字符串,则匹配正则表达式

Cherrio JS返回父div的所有图像SRC