【问题标题】:Make tables render as one next & materialui使表格呈现为下一个和materialui
【发布时间】:2022-02-15 11:46:56
【问题描述】:

目前我正在使用 NextJs 和 MaterialUI 来呈现一个表格,其中包含我在 Strapi 中创建的 API 的结果。

问题

目前的问题是我正在使用带有道具的表格组件,然后我将其导入页面并将道具映射到来自 GraphQl 请求的 api 响应(我使用 Apollo),我希望数据创建多行而不是多个表。

我们可以从图像中看到,当使用道具时,它会渲染两个表格,但结果是正确的。但是,如果我在表组件中映射数据,它会创建多行,这是我希望它工作的方式,但使用道具,所以我不只是创建十个或更多表。我在下面留下了代码。

如何使用带有 props 的表格但不使用它创建多个表格?

测试页面

import { Heading, VStack } from "@chakra-ui/react";
import { useQuery, gql } from "@apollo/client";
import { Typography } from "@mui/material";
import React from "react";
import { TableTwo } from "../src/components/UI/tableTwo";
import { TestingTable } from "../src/components/UI/tableTest";

const British = gql`
  query {
    britishes {
      data {
        attributes {
          Role_Name
          British_Roles {
            role_name
            Primary
            Primary_Sights
            Primary_Firing_Modes
            Primary_Magazine_Amount
            Primary_Magazine_Round_Amount
            Secondary
            Secondary_Firing_Modes
            Secondary_Sights
            Secondary_Magazine_Amount
            Secondary_Magazine_Round_Amount
            Secondary_Knife
          }
          British_Role_Extras {
            __typename
            ... on ComponentLoadoutsThirdSlot {
              Third_Slot_Item
              Item_Amount
            }
            __typename
            ... on ComponentLoadoutsForthSlot {
              Forth_Slot_Item
              Item_Amount
            }
            __typename
            ... on ComponentLoadoutsFifthSlot {
              Fith_Slot_Item
              Item_Amount
            }
            __typename
            ... on ComponentLoadoutsSixthSlot {
              Sixth_Slot_Item
              Item_Amount
            }
          }
        }
      }
    }
  }
`;

export default function Testing() {
  const { loading, error, data } = useQuery(British);

  if (loading) return <p>Loading...</p>;
  if (error) return console.log("Api request error", error), (<p>Error :(</p>);

  return (
    <VStack>
      <Typography variant="h3">Testing with axios & GraphQL</Typography>
      {data.britishes.data.map((british) => (
        <React.Fragment>
          <TableTwo
            id={british.attributes.Role_Name}
            roll_name={british.attributes.Role_Name}
            primary={british.attributes.British_Roles[0].Primary}
            primaryMag={
              british.attributes.British_Roles[0].Primary_Magazine_Amount
            }
            secondary={british.attributes.British_Roles[0].Secondary}
            secondaryKnife={british.attributes.British_Roles[0].Secondary_Knife}
          />
        </React.Fragment>
      ))}
      <TestingTable />
    </VStack>
  );
}

带道具的桌子

import * as React from "react";
import {
  Table,
  styled,
  TableBody,
  TableCell,
  tableCellClasses,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
} from "@mui/material";

const StyledTableCell = styled(TableCell)(({ theme }) => ({
  [`&.${tableCellClasses.head}`]: {
    backgroundColor: theme.palette.common.black,
    color: theme.palette.common.white,
  },
  [`&.${tableCellClasses.body}`]: {
    fontSize: 14,
  },
}));

const StyledTableRow = styled(TableRow)(({ theme }) => ({
  "&:nth-of-type(odd)": {
    backgroundColor: theme.palette.action.hover,
  },
  // hide last border
  "&:last-child td, &:last-child th": {
    border: 0,
  },
}));

export const TableTwo = (props) => {
  return (
    <React.Fragment>
      <TableContainer component={Paper}>
        <Table sx={{ minWidth: 700 }} aria-label="customized table">
          <TableHead>
            <TableRow>
              <StyledTableCell>Roll</StyledTableCell>
              <StyledTableCell align="right">Primary</StyledTableCell>
              <StyledTableCell align="right">
                Primary Magazine Amount
              </StyledTableCell>
              <StyledTableCell align="right">Secondary</StyledTableCell>
              <StyledTableCell align="right">Secondary Meele</StyledTableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            <StyledTableRow key={props.id}>
              <StyledTableCell component="th" scope="row">
                {props.roll_name}
              </StyledTableCell>
              <StyledTableCell align="right">{props.primary}</StyledTableCell>
              <StyledTableCell align="right">
                {props.primaryMag}
              </StyledTableCell>
              <StyledTableCell align="right">{props.secondary}</StyledTableCell>
              <StyledTableCell align="right">
                {props.secondaryKnife}
              </StyledTableCell>
            </StyledTableRow>
          </TableBody>
        </Table>
      </TableContainer>
    </React.Fragment>
  );
};

内部有映射的表格

import * as React from "react";
import {
  Table,
  styled,
  TableBody,
  TableCell,
  tableCellClasses,
  TableContainer,
  TableHead,
  TableRow,
  Paper,
} from "@mui/material";
import { useQuery, gql } from "@apollo/client";

const British = gql`
  query {
    britishes {
      data {
        attributes {
          Role_Name
          British_Roles {
            role_name
            Primary
            Primary_Sights
            Primary_Firing_Modes
            Primary_Magazine_Amount
            Primary_Magazine_Round_Amount
            Secondary
            Secondary_Firing_Modes
            Secondary_Sights
            Secondary_Magazine_Amount
            Secondary_Magazine_Round_Amount
            Secondary_Knife
          }
          British_Role_Extras {
            __typename
            ... on ComponentLoadoutsThirdSlot {
              Third_Slot_Item
              Item_Amount
            }
            __typename
            ... on ComponentLoadoutsForthSlot {
              Forth_Slot_Item
              Item_Amount
            }
            __typename
            ... on ComponentLoadoutsFifthSlot {
              Fith_Slot_Item
              Item_Amount
            }
            __typename
            ... on ComponentLoadoutsSixthSlot {
              Sixth_Slot_Item
              Item_Amount
            }
          }
        }
      }
    }
  }
`;

const StyledTableCell = styled(TableCell)(({ theme }) => ({
  [`&.${tableCellClasses.head}`]: {
    backgroundColor: theme.palette.common.black,
    color: theme.palette.common.white,
  },
  [`&.${tableCellClasses.body}`]: {
    fontSize: 14,
  },
}));

const StyledTableRow = styled(TableRow)(({ theme }) => ({
  "&:nth-of-type(odd)": {
    backgroundColor: theme.palette.action.hover,
  },
  // hide last border
  "&:last-child td, &:last-child th": {
    border: 0,
  },
}));

export const TestingTable = (props) => {
  const { loading, error, data } = useQuery(British);

  if (loading) return <p>Loading...</p>;
  if (error) return console.log("Api request error", error), (<p>Error :(</p>);

  return (
    <React.Fragment>
      <TableContainer component={Paper}>
        <Table sx={{ minWidth: 700 }} aria-label="customized table">
          <TableHead>
            <TableRow>
              <StyledTableCell>Roll</StyledTableCell>
              <StyledTableCell align="right">Primary</StyledTableCell>
              <StyledTableCell align="right">
                Primary Magazine Amount
              </StyledTableCell>
              <StyledTableCell align="right">Secondary</StyledTableCell>
              <StyledTableCell align="right">Secondary Meele</StyledTableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {data.britishes.data.map((british) => (
              <StyledTableRow key={british.attributes.Role_Name}>
                <StyledTableCell component="th" scope="row">
                  {british.attributes.Role_Name}
                </StyledTableCell>
                <StyledTableCell align="right">
                  {british.attributes.British_Roles[0].Primary}
                </StyledTableCell>
                <StyledTableCell align="right">
                  {british.attributes.British_Roles[0].Primary_Magazine_Amount}
                </StyledTableCell>
                <StyledTableCell align="right">
                  {british.attributes.British_Roles[0].Secondary}
                </StyledTableCell>
                <StyledTableCell align="right">
                  {british.attributes.British_Roles[0].Secondary_Knife}
                </StyledTableCell>
              </StyledTableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </React.Fragment>
  );
};

邮递员返回数据

{
    "data": {
        "britishes": {
            "data": [
                {
                    "attributes": {
                        "Role_Name": "British Squad Lead (Iron Sights)",
                        "British_Roles": [
                            {
                                "role_name": "British Squad Lead (Iron Sights)",
                                "Primary": "L85A2 + Foregrip + Bipod",
                                "Primary_Sights": "Iron Sights",
                                "Primary_Firing_Modes": "Auto/Single",
                                "Primary_Magazine_Amount": 7,
                                "Primary_Magazine_Round_Amount": 30,
                                "Secondary": "L131A1",
                                "Secondary_Firing_Modes": "Single",
                                "Secondary_Sights": "Iron Sights",
                                "Secondary_Magazine_Amount": 2,
                                "Secondary_Magazine_Round_Amount": null,
                                "Secondary_Knife": "SA80 Bayonet"
                            }
                        ],
                        "British_Role_Extras": [
                            {
                                "__typename": "ComponentLoadoutsThirdSlot",
                                "Third_Slot_Item": "L109A1 Fragmentation Grenade",
                                "Item_Amount": 2
                            },
                            {
                                "__typename": "ComponentLoadoutsForthSlot",
                                "Forth_Slot_Item": "L132A1 White Smoke Grenade",
                                "Item_Amount": 2
                            },
                            {
                                "__typename": "ComponentLoadoutsForthSlot",
                                "Forth_Slot_Item": "L152A1 Orange Smoke Grenade",
                                "Item_Amount": 1
                            },
                            {
                                "__typename": "ComponentLoadoutsForthSlot",
                                "Forth_Slot_Item": "L152A1 Yellow Smoke Grenade",
                                "Item_Amount": 1
                            },
                            {
                                "__typename": "ComponentLoadoutsFifthSlot",
                                "Fith_Slot_Item": "Field Dressing",
                                "Item_Amount": 2
                            },
                            {
                                "__typename": "ComponentLoadoutsSixthSlot",
                                "Sixth_Slot_Item": "Field Binoculars",
                                "Item_Amount": 1
                            },
                            {
                                "__typename": "ComponentLoadoutsSixthSlot",
                                "Sixth_Slot_Item": "Rally Point",
                                "Item_Amount": 1
                            }
                        ]
                    }
                },
                {
                    "attributes": {
                        "Role_Name": "British Squad Lead (SUSAT)",
                        "British_Roles": [
                            {
                                "role_name": "British Squad Lead (SUSAT)",
                                "Primary": "L85A2 + Foregrip + Bipod",
                                "Primary_Sights": "SUSAT Scope",
                                "Primary_Firing_Modes": "Auto/Single",
                                "Primary_Magazine_Amount": 7,
                                "Primary_Magazine_Round_Amount": 30,
                                "Secondary": "L131A1",
                                "Secondary_Firing_Modes": "Single",
                                "Secondary_Sights": "Iron Sights",
                                "Secondary_Magazine_Amount": 2,
                                "Secondary_Magazine_Round_Amount": null,
                                "Secondary_Knife": "SA80 Bayonet"
                            }
                        ],
                        "British_Role_Extras": [
                            {
                                "__typename": "ComponentLoadoutsThirdSlot",
                                "Third_Slot_Item": "L109A1 Fragmentation Grenade",
                                "Item_Amount": 1
                            },
                            {
                                "__typename": "ComponentLoadoutsForthSlot",
                                "Forth_Slot_Item": "L132A1 White Smoke Grenade",
                                "Item_Amount": 2
                            },
                            {
                                "__typename": "ComponentLoadoutsForthSlot",
                                "Forth_Slot_Item": "L152A1 Orange Smoke Grenade",
                                "Item_Amount": 1
                            },
                            {
                                "__typename": "ComponentLoadoutsForthSlot",
                                "Forth_Slot_Item": "L152A1 Yellow Smoke Grenade",
                                "Item_Amount": 1
                            },
                            {
                                "__typename": "ComponentLoadoutsFifthSlot",
                                "Fith_Slot_Item": "Field Dressing",
                                "Item_Amount": 2
                            },
                            {
                                "__typename": "ComponentLoadoutsSixthSlot",
                                "Sixth_Slot_Item": "Field Binoculars",
                                "Item_Amount": 1
                            },
                            {
                                "__typename": "ComponentLoadoutsSixthSlot",
                                "Sixth_Slot_Item": "Rally Point",
                                "Item_Amount": 1
                            }
                        ]
                    }
                }
            ]
        }
    }
}

开发工具控制台日志

【问题讨论】:

    标签: javascript reactjs next.js apollo strapi


    【解决方案1】:

    您需要删除测试组件中的 .map 调用,它会为每个条目创建一个新表。

    return (
        <VStack>
          <Typography variant="h3">Testing with axios & GraphQL</Typography>
              <TableTwo
                id={british.attributes.Role_Name}
                roll_name={british.attributes.Role_Name}
                primary={british.attributes.British_Roles[0].Primary}
                primaryMag={
                  british.attributes.British_Roles[0].Primary_Magazine_Amount
                }
                secondary={british.attributes.British_Roles[0].Secondary}
                secondaryKnife={british.attributes.British_Roles[0].Secondary_Knife}
              />
          <TestingTable />
        </VStack>
      );
    

    【讨论】:

    • 嗯,好吧,我不确定这一点,因为我感觉它只会呈现一个结果,我像这样使用它{data.britishes.data[0].attributes.Role_Name},它只会返回一个结果。但我不明白为什么。我有一种感觉是由于它从 GrahpQl 返回的方式,我在帖子中添加了 API 结果。任何提示将是巨大的
    • 如果你只想渲染一个,你根本不需要地图。 Map 专门用于为数组中的每个元素迭代地渲染标记。我无法真正弄清楚您的数据是如何构造的,我认为您需要使其符合某种层次结构,或者只返回一个对象数组,其中包含一行所需的所有数据。因为它是非常令人困惑的。而且您似乎将很多未使用的道具传递给您的表格组件。
    • 好的,我会探索其他选项,谢谢。
    猜你喜欢
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2019-04-03
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多