Как сопоставить массив объектов в React, а затем условно отобразить компонент на основе предыдущего значения?

У меня есть это представление планирования, которое я хочу создать. Однако я хочу, чтобы поле даты появлялось только в том случае, если оно имеет уникальную дату (а затем список времени, указанный ниже). Вот codesandbox.

Я хочу, чтобы это выглядело примерно так: этим.

Но вместо этого в настоящее время поле даты отображается с каждой итерацией. Я не могу условно отображать поля даты на основе текущей и предыдущей даты. Я пытался сопоставить данные и получить доступ к ранее повторенной дате и сравнить, равны они или нет, но это не работает так, как я этого хочу. Я покажу, что я пробовал ниже. Выдает ошибку, когда я пытаюсь получить доступ к предыдущей дате.

Есть ли какие-либо предложения о том, как этого добиться?

    import "./styles.css";
import React from "react";
import styled from "styled-components";
import { format, isSameDay } from "date-fns";

const Student = styled.p`
  font-size: 16px;
  font-weight: bold;
  margin: 0px 20px 0px 20px;
`;

const NameContainer = styled.div`
  display: flex;
  flex-direction: row;
  align-items: center;
  margin-top: 10px;
`;

const Teacher = styled.p`
  font-size: 16px;
  margin: 0px;
`;

const BottomContainer = styled.div`
  display: flex;
  flex-direction: row;
  align-items: center;
  padding-left: 95px;
`;

const SubjectLabel = styled.p`
  font-size: 12px;
  font-weight: bold;
  margin-right: 5px;
`;

const Subject = styled.p`
  font-size: 14px;
`;

const Difficulty = styled.p`
  font-size: 14px;
  font-weight: bold;
  color: red;
  margin-left: 10px;
`;

const Row = styled.div`
  text-decoration: none;
  cursor: pointer;
  :hover {
    background: grey;
  }
`;

const DateBox = styled.div`
  display: flex;
  width: 70px;
  height: 25px;
  background-color: pink;
  justify-content: center;
`;

const TimeBox = styled.div`
  display: flex;
  flex-direction: row;
  justify-content: center;
  width: 70px;
  height: 25px;
  border-radius: 15px;
  border: 1px solid black;
`;

const Time = styled.p`
  font-size: 10px;
  font-weight: 600;
`;

export const schedules = [
  {
    id: "1",
    student: "Faye",
    subject: "Math",
    difficulty: "Extreme",
    dateSent: new Date("December 17, 2020"),
    to: "Mr Skip"
  },
  {
    id: "2",
    student: "Jen",
    subject: "English",
    difficulty: "Easy",
    dateSent: new Date("December 17, 2020"),
    to: "Mr Skip"
  },
  {
    id: "3",
    student: "Martin",
    subject: "Math",
    difficulty: "Easy",
    dateSent: new Date("December 13, 2020"),
    to: "Mr Skip"
  },
  {
    id: "4",
    student: "Steve",
    subject: "Geography",
    difficulty: "Hard",
    dateSent: new Date("December 13, 2020"),
    to: "Mr Skip"
  }
];

export default function App() {
  return (
    <div>
      {schedules.length > 0 &&
        schedules.map((schedule, i, arr) => {
          const previousArray = arr[i - 1];
          // console.log("this is previous array", previousArray);
          // console.log("this is previous date", previousArray.dateSent); //this returns undefined
          return (
            <Row key={schedule.id}>
                {schedule.dateSent[i-1] !== schedule.dateSent) ? 
                (
                <DateBox>{format(schedule.dateSent, 'MMM dd')}</DateBox>
                ) : (
                null
                )}
              <NameContainer>
                <TimeBox>
                  <Time>{format(schedule.dateSent, "h:mm a")}</Time>
                </TimeBox>
                <Student>{schedule.student}</Student>
                <Teacher> For: {schedule.to}</Teacher>
              </NameContainer>
              <BottomContainer>
                <SubjectLabel>Subject</SubjectLabel>
                <Subject>{schedule.subject}</Subject>
                <Difficulty>{schedule.difficulty}</Difficulty>
              </BottomContainer>
            </Row>
          );
        })}
    </div>
  );
}

А вот и codesandbox!


person vaitaka    schedule 30.04.2021    source источник
comment
Проблема с доступом к предыдущей дате здесь заключается в том, что когда i = 0 (для первого элемента), то ваш previousArray = arr [-1], который не определен и выдает ошибку. Остальные элементы могут успешно получить доступ к предыдущей дате.   -  person Shubham Periwal    schedule 01.05.2021
comment
О, я вижу. Я не думал об этом. Спасибо за объяснение!   -  person vaitaka    schedule 01.05.2021


Ответы (1)


Я добавил здесь проверку, чтобы проверить, являются ли i>0 и дата! = предыдущая дата, затем показать Datebox, иначе просто добавьте строку

{schedules.length > 0 &&
    schedules.map((schedule, i, arr) => {
      const previousDate = arr[i - 1];
        return (
          <Row key={schedule.id}>
            { i==0 || (previousDate &&
          previousDate.dateSent.getDate() !== schedule.dateSent.getDate()) ?
                <DateBox>{format(schedule.dateSent, "MMM dd")}</DateBox> :
                 <></>
            }
            

            <NameContainer>
              <TimeBox>
                <Time>{format(schedule.dateSent, "h:mm a")}</Time>
              </TimeBox>
              <Student>{schedule.student}</Student>
              <Teacher> For: {schedule.to}</Teacher>
            </NameContainer>
            <BottomContainer>
              <SubjectLabel>Subject</SubjectLabel>
              <Subject>{schedule.subject}</Subject>
              <Difficulty>{schedule.difficulty}</Difficulty>
            </BottomContainer>
          </Row>
        );
    })}

Вывод соответствует ожидаемому

Вот песочница

person Shubham Periwal    schedule 01.05.2021