主頁 > 軟體工程 > ReactJS基于id映射選擇陣列

ReactJS基于id映射選擇陣列

2022-06-01 03:57:21 軟體工程

我對 JavaScript 很陌生,希望有人能幫我解決這個問題。

我有一個顯示所有預定考試的頁面,當您按下“了解更多”時,會打開一個模式,讓您可以修改有關考試本身的資訊。目前,它顯示創建考試時選擇的設備以及其他可用設備,您應該能夠選擇/取消選擇,以便在需要時進行更改。問題是每次檢查都會打開不同的模式以僅顯示相應的資料。我通過映射顯示的所有考試資訊都可以到達“exams”嵌套陣列的內部陣列,所以當我需要打開模態以獲得特定內容時,我不知道如何在渲染之前初始化 const考試資訊。目前我正在映射所選設備的值,這不允許我像我應該的那樣更改選擇。

https://codesandbox.io/s/81xer5

import "./styles.css";
import React, { useState, useEffect } from "react";
import Box from "@mui/material/Box";
import Card from "@mui/material/Card";
import CardActions from "@mui/material/CardActions";
import CardContent from "@mui/material/CardContent";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import Modal from "@mui/material/Modal";
import Chip from "@mui/material/Chip";
import OutlinedInput from "@mui/material/OutlinedInput";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import FormControl from "@mui/material/FormControl";
import Select from "@mui/material/Select";

const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
  PaperProps: {
    style: {
      maxHeight: ITEM_HEIGHT * 4.5   ITEM_PADDING_TOP,
      width: 250
    }
  }
};

const style = {
  position: "absolute",
  top: "50%",
  left: "50%",
  transform: "translate(-50%, -50%)",
  width: 400,
  bgcolor: "background.paper",
  boxShadow: 24,
  p: 4,
  borderRadius: 1
};

export default function App() {
  const [exams, setExams] = useState([
    {
      id: "18897a8c-bd5b-4fc0-86d1-74ee509d46ee",
      name: "New Test",
      date: null,
      time: null,
      date2: "2022-06-20",
      time2: "15:30",
      students: [
        {
          id: "749ce920-2462-457a-8af3-26ff9c00dda5",
          username: "student1",
          email: "[email protected]",
          firstName: "Student",
          lastName: "Studentov",
          roleName: "STUDENT"
        },
        {
          id: "90289548-19bb-480b-81e3-c36340debbc7",
          username: "student2",
          email: "[email protected]",
          firstName: "Student",
          lastName: "Studentov",
          roleName: "STUDENT"
        },
        {
          id: "dfe50fe5-ef9d-480e-aa6c-2f5c81bb22da",
          username: "student3",
          email: "[email protected]",
          firstName: "Student",
          lastName: "Studentov",
          roleName: "STUDENT"
        }
      ],
      staff: [
        {
          id: "a3b53ed0-63fc-4f77-a8dc-74915d6aefea",
          username: "staff",
          email: "[email protected]",
          firstName: "Staff",
          lastName: "Staffov",
          roleName: "STAFF"
        }
      ],
      rooms: [
        {
          id: "a49f18cb-4fe8-4a2c-a665-4361c5401f31",
          number: 100,
          nrOfSeats: 20
        },
        {
          id: "5c46e888-fce4-4c1b-a8ec-e04d32a5cf6c",
          number: 400,
          nrOfSeats: 10
        }
      ],
      equipment: [
        {
          id: "08506d1b-30ce-43d2-a0b8-74f87082e356",
          name: "Crane",
          availability: true
        }
      ]
    },
    {
      id: "65b7ecd2-ba30-4369-9f13-9186dc5cc73c",
      name: "Crane Exam",
      date: null,
      time: null,
      date2: null,
      time2: null,
      students: [
        {
          id: "749ce920-2462-457a-8af3-26ff9c00dda5",
          username: "student1",
          email: "[email protected]",
          firstName: "Student",
          lastName: "Studentov",
          roleName: "STUDENT"
        },
        {
          id: "90289548-19bb-480b-81e3-c36340debbc7",
          username: "student2",
          email: "[email protected]",
          firstName: "Student",
          lastName: "Studentov",
          roleName: "STUDENT"
        },
        {
          id: "dfe50fe5-ef9d-480e-aa6c-2f5c81bb22da",
          username: "student3",
          email: "[email protected]",
          firstName: "Student",
          lastName: "Studentov",
          roleName: "STUDENT"
        }
      ],
      staff: [
        {
          id: "a3b53ed0-63fc-4f77-a8dc-74915d6aefea",
          username: "staff",
          email: "[email protected]",
          firstName: "Staff",
          lastName: "Staffov",
          roleName: "STAFF"
        }
      ],
      rooms: [
        {
          id: "a49f18cb-4fe8-4a2c-a665-4361c5401f31",
          number: 100,
          nrOfSeats: 20
        },
        {
          id: "5c46e888-fce4-4c1b-a8ec-e04d32a5cf6c",
          number: 400,
          nrOfSeats: 10
        }
      ],
      equipment: [
        {
          id: "08506d1b-30ce-43d2-a0b8-74f87082e356",
          name: "Crane",
          availability: true
        },
        {
          id: "be1da3c9-7192-459f-bdba-767e005eaac9",
          name: "Killer Robot",
          availability: true
        }
      ]
    }
  ]);

  const [equipment, setEquipment] = useState([
    {
      id: "08506d1b-30ce-43d2-a0b8-74f87082e356",
      name: "Crane",
      availability: true
    },
    {
      id: "7a1716c7-3398-4e3d-9523-7ba4a102a79b",
      name: "Lift",
      availability: true
    },
    {
      id: "be1da3c9-7192-459f-bdba-767e005eaac9",
      name: "Killer Robot",
      availability: true
    }
  ]);

  const initialShowState = Object.fromEntries(
    exams.map((data) => [data.id, false])
  );
  const [show, setShow] = React.useState(initialShowState);
  const toggleShow = (id) =>
    setShow((prev) => {
      return { ...prev, [id]: !prev[id] };
    });
  console.log({ show });

  const [value, setValue] = React.useState([]); //this is what the select chip uses by default

  const handleChange = (e) => {
    const {
      target: { value }
    } = e;

    console.log(value);
    setValue(
      // On autofill we get a the stringified value.
      typeof value === "string" ? value.split(",") : value
    );
  };

  return (
    <div className="App">
      {exams.map((data, key) => {
        return (
          <div key={key} style={{ width: "300px", display: "inline-block" }}>
            <Box
              sx={{
                minWidth: 300,
                maxWidth: 300,
                display: "inline-block",
                paddingTop: "10px",
                paddingLeft: "10px"
              }}
            >
              <Card variant="outlined">
                <React.Fragment>
                  <CardContent>
                    <Typography variant="h5" component="div">
                      {data.name}
                    </Typography>
                  </CardContent>

                  <CardActions>
                    <Button size="small" onClick={() => toggleShow(data.id)}>
                      Learn More
                    </Button>
                  </CardActions>
                </React.Fragment>
              </Card>
            </Box>

            <Modal open={show[data.id]} onClose={() => toggleShow(data.id)}>
              <Box sx={style}>
                <Typography
                  component={"span"}
                  id="transition-modal-description"
                  sx={{ mt: 2 }}
                >
                  <FormControl sx={{ m: 1, width: 300 }}>
                    <InputLabel id="demo-multiple-chip-label">Chip</InputLabel>
                    <Select
                      multiple
                      value={data.equipment.map((sub) => sub.id)}
                      // value={value}
                      onChange={handleChange}
                      input={
                        <OutlinedInput id="select-multiple-chip" label="Chip" />
                      }
                      renderValue={(selected) => {
                        return (
                          <Box
                            sx={{ display: "flex", flexWrap: "wrap", gap: 0.5 }}
                          >
                            {selected.map((value) => {
                              const option = equipment.find(
                                (o) => o.id === value
                              );
                              return <Chip key={value} label={option.name} />;
                            })}
                          </Box>
                        );
                      }}
                      MenuProps={MenuProps}
                    >
                      {equipment.map((option) => (
                        <MenuItem key={option.id} value={option.id}>
                          {option.name}
                        </MenuItem>
                      ))}
                    </Select>
                  </FormControl>
                </Typography>
              </Box>
            </Modal>
          </div>
        );
      })}
    </div>
  );
}

uj5u.com熱心網友回復:

繼續我上面的評論,您在函式<Modal>內部添加了一個map,這將為每次考試安裝一個<Modal>元素,這對性能不利并且更難以實作。

您要做的是只有一個模態,單擊“了解更多”后,您將活動考試保存在一個狀態中,該模態使用此狀態顯示正確的資料。您還希望在考試和模態之間拆分邏輯,以使其更易于實施。

這是一個示例代碼,我已將陣列移到組件外部以使代碼更清晰:

const EXAMS = [...];
const EQUIPMENTS = [...];

export default function App() {
  const [exams, setExams] = useState(EXAMS);
  const [equipment, setEquipment] = useState(EQUIPMENTS);

  const [modalExam, setModalExam] = useState(null);

  return (
    <div className="App">
      {exams.map((data, key) => {
        return (
          <div key={key} style={{ width: "300px", display: "inline-block" }}>
            <Box
              sx={{
                minWidth: 300,
                maxWidth: 300,
                display: "inline-block",
                paddingTop: "10px",
                paddingLeft: "10px",
              }}
            >
              <Card variant="outlined">
                <React.Fragment>
                  <CardContent>
                    <Typography variant="h5" component="div">
                      {data.name}
                    </Typography>
                  </CardContent>

                  <CardActions>
                    <Button size="small" onClick={() => setModalExam(data)}>
                      Learn More
                    </Button>
                  </CardActions>
                </React.Fragment>
              </Card>
            </Box>
          </div>
        );
      })}

      <ModalExam
        equipment={equipment}
        exam={modalExam}
        onClose={() => setModalExam(null)}
      />
    </div>
  );
}

function ModalExam({ exam, equipment, onClose }) {
  const [chipValue, setChipValue] = useState([]);

  useEffect(() => {
    if (exam) {
      setChipValue(exam.equipment.map((sub) => sub.id));
    }
  }, [exam]);

  const handleChange = (e) => {
    const {
      target: { value },
    } = e;

    console.log(value);

    setChipValue(typeof value === "string" ? value.split(",") : value);
  };

  return (
    <Modal open={exam !== null} onClose={onClose}>
      {exam && (
        <Box sx={style}>
          <Typography
            component={"span"}
            id="transition-modal-description"
            sx={{ mt: 2 }}
          >
            <p>{exam.name}</p>

            <FormControl sx={{ m: 1, width: 300 }}>
              <InputLabel id="demo-multiple-chip-label">Chip</InputLabel>
              <Select
                multiple
                value={chipValue}
                // value={value}
                onChange={handleChange}
                input={<OutlinedInput id="select-multiple-chip" label="Chip" />}
                renderValue={(selected) => {
                  return (
                    <Box sx={{ display: "flex", flexWrap: "wrap", gap: 0.5 }}>
                      {selected.map((value) => {
                        const option = equipment.find((o) => o.id === value);
                        return <Chip key={value} label={option.name} />;
                      })}
                    </Box>
                  );
                }}
                MenuProps={MenuProps}
              >
                {equipment.map((option) => (
                  <MenuItem key={option.id} value={option.id}>
                    {option.name}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          </Typography>
        </Box>
      )}
    </Modal>
  );
}

看看當你拆分邏輯時它變得多么簡單。這是沙箱:https ://codesandbox.io/s/hedk9g

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/483805.html

標籤:javascript 数组 反应 字典 材料-ui

上一篇:從給定索引的陣列中回傳字串元素

下一篇:回圈陣列中的多個陣列

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more