我如何映射 React 中的对象数组,然后根据先前的值有条件地渲染组件?
How do I map over an array of objects in React and then conditionally render a component based on a previous value?
我有这个要创建的日程安排视图。但是,我希望日期框仅在具有唯一日期(然后是下面列出的时间列表)时出现。这是 codesandbox.
我希望它看起来像 this。
但目前日期框在每次迭代时都会呈现。
我无法根据当前日期和上一个日期有条件地呈现日期框。我一直在尝试映射数据并访问先前迭代的日期并比较它们是否相等,但它没有像我想要的那样工作。我将在下面展示我尝试过的内容。当我尝试访问上一个日期时它抛出错误。
对于如何实现这一点有什么建议吗?
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!
我在这里添加了一个检查以检查是否 i>0 和 date != previousDate,然后显示 Datebox 否则只需添加 row
{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>
);
})}
Output 符合预期
这是sandbox
我有这个要创建的日程安排视图。但是,我希望日期框仅在具有唯一日期(然后是下面列出的时间列表)时出现。这是 codesandbox.
我希望它看起来像 this。
但目前日期框在每次迭代时都会呈现。 我无法根据当前日期和上一个日期有条件地呈现日期框。我一直在尝试映射数据并访问先前迭代的日期并比较它们是否相等,但它没有像我想要的那样工作。我将在下面展示我尝试过的内容。当我尝试访问上一个日期时它抛出错误。
对于如何实现这一点有什么建议吗?
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!
我在这里添加了一个检查以检查是否 i>0 和 date != previousDate,然后显示 Datebox 否则只需添加 row
{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>
);
})}
Output 符合预期
这是sandbox