Состояние реакции из реквизита, который не обновляется (даже при деструктуризации и использовании разных ключей)

Извините за длинный вопрос заранее, но я боролся с этим в течение некоторого времени

Чтобы дать некоторый контекст того, что я пытаюсь выполнить, я загружаю эту таблицу, когда загружается мое приложение.

И когда я нажимаю кнопку внутри красного квадрата, пользователь переходит в режим редактирования.

В режиме редактирования пользователь должен иметь возможность, например, переключатьHigh School Core(внутри зеленого квадрата) и отмените изменение, нажав кнопку (внутри синего квадрата)

Дело в том, что он не работает, этот флажок не должен быть установлен, потому что этоDiscard Changesкнопка только устанавливаетeditModeсостояние на false, и при этом таблица должна быть создана путем сопоставления другого объекта:const whichCourse = editMode ? modifiedValues : originalValues

Исходные данные, из которыхoriginalValuesиmodifiedValuesсоздаются, передается в<Table />компонент в качестве реквизита (это требование для этого приложения) изApp.tsx

      import { v4 as uuidv4 } from "uuid";
import { Container } from "@mui/material";

import Table from "./Table";

const ID1 = uuidv4();
const ID2 = uuidv4();
const ID3 = uuidv4();

export const typedData = {
  bundles: [
    {
      id: ID1,
      name: "High School Core",
    },
    {
      id: ID2,
      name: "Middle School Core",
    },
    {
      id: ID3,
      name: "Elementary School Core",
    },
  ],
  schools: [
    {
      id: uuidv4(),
      name: "First School",
      licensedproducts: [ID1, ID2],
    },
    {
      id: uuidv4(),
      name: "Second School",
      licensedproducts: [ID2, ID3],
    },
  ],
};

export default function App() {
  return (
    <Container>
      <Table propsData={typedData} />
    </Container>
  );
}

ФайлTable.tsxсодержит следующее для визуализации пользовательского интерфейса и обработки всей логики

      import { useState, useEffect } from "react";
import CheckIcon from "@mui/icons-material/Check";
import { Box, Grid, Button, Checkbox } from "@mui/material";

import { typedData } from "./App";

const tableStyles = {
  display: "block",
  overflowX: "auto",
  paddingTop: "36px",
  whiteSpace: "nowrap",
  fontFamily: "Helvetica Neue",
  "& table": {
    width: "100%",
    textAlign: "center",
    borderCollapse: "collapse",
  },
  "& th, td": {
    px: "17px",
    color: "#1E1E24",
    fontSize: "14px",
    fontWeight: "400",
    lineHeight: "40px",
  },
  "& th": {
    borderBottom: "2px solid #00006D",
  },
  "& td": {
    borderBottom: "1px solid #dddddd",
  },
  "& th:nth-of-type(1), td:nth-of-type(1), th:nth-of-type(2), td:nth-of-type(2)": {
    textAlign: "left",
  },
};

export default function Table({ propsData }: { propsData: typeof typedData }) {
  const [editMode, setEditMode] = useState(false);

  const [originalValues, setOriginalValues] = useState({ ...propsData });
  const [modifiedValues, setModifiedValues] = useState({ ...propsData });

  useEffect(() => {
    console.log("running useEffect");
    setOriginalValues({ ...propsData });
    setModifiedValues({ ...propsData });
  }, [propsData]);

  const whichCourse = editMode ? modifiedValues : originalValues;
  const keyComplement = editMode ? "yes" : "not";

  const toggleEdit = () => {
    setEditMode((current) => !current);
  };

  const saveButton = () => {
    setOriginalValues(modifiedValues);
  };

  return (
    <Box sx={{ textAlign: "center", pt: "10px" }}>
      <Grid container spacing={2}>
        <Grid item xs>
          <Button variant="contained" onClick={toggleEdit}>
            {editMode ? "Discard changes" : `Edit Mode - ${keyComplement}`}
          </Button>
        </Grid>
        {editMode && (
          <Grid item xs>
            <Button variant="contained" onClick={saveButton}>
              Save changes
            </Button>
          </Grid>
        )}
      </Grid>
      <Box sx={tableStyles}>
        <Box component="table" sx={{ overflowX: "auto" }} tabIndex={0}>
          <thead>
            <tr>
              <Box component="th">ID</Box>
              <Box component="th">School Name</Box>
              {whichCourse.bundles.map((thisBundle) => {
                return (
                  <Box component="th" key={`th-${thisBundle.id}-${keyComplement}`}>
                    {thisBundle.name}
                  </Box>
                );
              })}
            </tr>
          </thead>
          <tbody>
            {whichCourse.schools.map((thisSchool, currentIndex) => {
              return (
                <tr key={`td-${thisSchool.id}-${keyComplement}`}>
                  <Box component="td">{thisSchool.id}</Box>
                  <Box component="td">{thisSchool.name}</Box>
                  {whichCourse.bundles.map((thisBundle) => {
                    const isEnabled = thisSchool.licensedproducts.includes(thisBundle.id);
                    return (
                      <Box component="td" key={`td-${thisBundle.id}-${keyComplement}`}>
                        {editMode ? (
                          <Checkbox
                            size="small"
                            checked={isEnabled}
                            sx={{
                              color: "#000000",
                              "&.Mui-checked": {
                                color: "#3F51B5",
                              },
                            }}
                            onChange={() =>
                              setModifiedValues((currentValue) => {
                                if (isEnabled) {
                                  currentValue.schools[currentIndex].licensedproducts = currentValue.schools[currentIndex].licensedproducts.filter((value) => value !== thisBundle.id);
                                } else {
                                  currentValue.schools[currentIndex].licensedproducts.push(thisBundle.id);
                                }
                                return { ...currentValue };
                              })
                            }
                          />
                        ) : (
                          isEnabled && <CheckIcon sx={{ verticalAlign: "middle" }} />
                        )}
                      </Box>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </Box>
      </Box>
    </Box>
  );
}

Я создал очень простое репо с этим кодом и развертыванием страниц CloudFlare.

0 ответов

Другие вопросы по тегам