Reactjs 渲染日历&;与客户的约会

Reactjs 渲染日历&;与客户的约会,reactjs,calendar,momentjs,react-hooks,Reactjs,Calendar,Momentjs,React Hooks,我正在尝试为每个用户创建一个类似的日历 (忽略样式,这不是最终结果): 我有一系列来自后端的约会,我想根据日期和时间将它们呈现在应该的位置 我找不到一个很好的实践,我想使用数据属性并在约会加载后更改它们,但React网站说要避免这样做。 所以我能想到的唯一方法就是每次渲染单元格(我不使用table,而是div)时都在appoints数组上运行,并检查时间是否相等。 我尽量避免使用它,因为在我看来这是一种糟糕的做法,每个渲染的DIV都必须在约会数组上运行,并检查其中一个是否按时间戳匹配 在渲染日

我正在尝试为每个用户创建一个类似的日历 (忽略样式,这不是最终结果):

我有一系列来自后端的约会,我想根据日期和时间将它们呈现在应该的位置

我找不到一个很好的实践,我想使用数据属性并在约会加载后更改它们,但React网站说要避免这样做。 所以我能想到的唯一方法就是每次渲染单元格(我不使用table,而是div)时都在appoints数组上运行,并检查时间是否相等。 我尽量避免使用它,因为在我看来这是一种糟糕的做法,每个渲染的DIV都必须在约会数组上运行,并检查其中一个是否按时间戳匹配

在渲染日历之后,是否有任何方法可以渲染它们?这样我就可以改变特定的单元格,避免不必要的循环

我使用React钩子和Redux作为前端

编辑: 这是我的密码

import React, { useEffect, useState, useMemo } from 'react';
import { useSelector } from 'react-redux';
import moment from 'moment';

function Calendar() {
    const calendarFromStore = useSelector(state => state.calendar);
    const [calendar, setCalendar] = useState({});
    const [settings, setSettings] = useState({
        currentWeek: [],
        diffWeeks: 0,
        totalAppointments: []
}); 

useEffect(() => {
    setCalendar(calendarFromStore);
    setSettings({ ...settings, currentWeek: getCurrentWeek })
}, [calendarFromStore]);

useEffect(() => {
    setSettings({ ...settings, currentWeek: getCurrentWeek })
}, [settings.diffWeeks])

const getCurrentWeek = useMemo(() => {
    let currentDate = moment().add(settings.diffWeeks, 'weeks');
    let days = [];
    for (let i = 3; i >= 0; i--) {
        days.push(moment(currentDate).subtract(i, 'days').format('dddd DD/MM/YY'));
    }
    for (let i = 1; i <= 3; i++) {
        days.push(moment(currentDate).add(i, 'days').format('dddd DD/MM/YY'));
    }
    return days;
}, [settings.diffWeeks])

const daysHeader = useMemo(() => {
    if (!settings.currentWeek) return;
    return settings.currentWeek.map((day, i) =>
        <div className={`day-title ${i === 3 && !settings.diffWeeks ? 'today' : ''}`} key={day}>
            <span className="day">{day.substring(0, day.indexOf(' '))}</span>
            <span className="date">{day.substring(day.indexOf(' '))}</span>
        </div>)
}, [settings.currentWeek, settings.diffWeeks]);

const timeline = useMemo(() => {
    let currTime = '10:00';
    const stopTime = '19:00';
    const interval = 15;
    let timesArr = [];
    while (currTime !== stopTime) {
        timesArr.push(currTime);
        currTime = moment(currTime, 'HH:mm').add(interval, 'minute').format('HH:mm');
    }
    setSettings({ ...settings, totalAppointments: timesArr })
    return timesArr;
}, [])

const convertStringToTimestamp = (day, time) => {
    const fixedDay = day.substring(day.indexOf(' '));
    return moment(`${fixedDay} ${time}`, 'DD/MM/YY HH:mm').unix();
}

const calendarApts = useMemo(() => {
    if (!settings.currentWeek) return;
    return settings.currentWeek.map(day =>
        <div className="line" key={day}>
            {timeline.map(time =>
                <div key={`${day} ${time}`}
                    time={convertStringToTimestamp(day, time)} onClick={() => console.log(day, time)}>
                </div>)
            }
        </div>
    )
}, [settings.currentWeek, timeline])

useMemo(() => {
    calendar.appointments && calendar.appointments.map(apt => apt);
}, [calendar.appointments])

const changeWeeks = val => {
    setSettings({ ...settings, diffWeeks: !val ? 0 : settings.diffWeeks + val })
}

return (
    <div className="calendar-container">
        <div className="navigation">
            <div className="last-buttons">
                <button onClick={() => changeWeeks(-5)}>Last month</button>
                <button onClick={() => changeWeeks(-1)}>Last week</button>
            </div>
            <button onClick={() => changeWeeks(0)}>Current Week</button>
            <div className="next-buttons">
                <button onClick={() => changeWeeks(1)}>Next week</button>
                <button onClick={() => changeWeeks(5)}>Next month</button>
            </div>
        </div>
        <div className="calendar-header">
            {daysHeader}
        </div>
        <div className="calendar-content">
            <div className="calendar-timeline">
                {timeline.map(time => <div key={time}><span>{time}</span></div>)}
            </div>
            <div className="calendar-vertical-lines">
                {calendarApts}
            </div>
        </div>
    </div>
)
}

export default Calendar;
import React,{useffect,useState,usemo}来自“React”;
从'react redux'导入{useSelector};
从“力矩”中导入力矩;
函数日历(){
const calendarFromStore=useSelector(state=>state.calendar);
const[calendar,setCalendar]=useState({});
常量[设置,设置]=使用状态({
当前周:[],
周数:0,,
总任命:[]
}); 
useffect(()=>{
设置日历(calendarFromStore);
设置设置({…设置,currentWeek:getCurrentWeek})
},[calendarFromStore]);
useffect(()=>{
设置设置({…设置,currentWeek:getCurrentWeek})
},[settings.diffWeeks])
const getCurrentWeek=useMoom(()=>{
让currentDate=moment().add(settings.diffWeeks,“weeks”);
让天数=[];
对于(设i=3;i>=0;i--){
推送(时刻(当前日期)。减去(i,'天')。格式('dddddd/MM/YY'));
}
for(设i=1;i{
如果(!settings.currentWeek)返回;
返回设置.currentWeek.map((天,i)=>
{day.substring(0,day.indexOf('')}
{day.substring(day.indexOf('')}
)
},[settings.currentWeek,settings.diffWeeks]);
常数时间线=使用备忘录(()=>{
让currTime='10:00';
常数停止时间='19:00';
常数间隔=15;
让timesArr=[];
while(currTime!==停止时间){
时差推送(currTime);
currTime=时刻(currTime,'HH:mm')。添加(间隔,'minute')。格式('HH:mm');
}
设置设置({…设置,TotalAppointment:timesArr})
返回时间段;
}, [])
const convertStringToTimestamp=(天、时间)=>{
常数fixedDay=日子字符串(日索引(“”));
返回时刻(`fixedDay}${time}`,`DD/MM/YY HH:MM').unix();
}
const calendarApts=useMoom(()=>{
如果(!settings.currentWeek)返回;
返回设置.currentWeek.map(日期=>
{timeline.map(时间=>
console.log(天、时间)}>
)
}
)
},[settings.currentWeek,timeline])
useMemo(()=>{
calendar.appoints&&calendar.appoints.map(apt=>apt);
},[日历.约会])
const changeWeeks=val=>{
设置设置({…设置,diffWeeks:!val?0:settings.diffWeeks+val})
}
返回(
changeWeeks(-5)}>上个月
changeWeeks(-1)}>上周
changeWeeks(0)}>当前周
changeWeeks(1)}>下周
changeWeeks(5)}>下个月
{daysHeader}
{timeline.map(时间=>{time}}
{calendarApts}
)
}
导出默认日历;

Hey Danivagas,你能展示一些代码吗?-我想应该是将数据单元与后端的参数关联起来。模式的结构是什么?我的意思是,当Apoint在10:45和10.01时,它应该在单元-[5,4]中呈现。可以使用循环或其他。如何创建此前端?它是一个数组或表?添加了我的代码,约会是一个对象数组,每个对象都有一个id,开始(时间戳)和客户名称。目前,每个约会都应与用户决定的相同,如果约会时间为15分钟,客户提交约会,则应在该单元格中显示,例如10:30到10:45。与其他日历不同,您可以将约会时间设置为10:35到10:50,时间介于…现在我宁愿不要下到这样的解决方案OK,据我所见,关键是日期和时间参数(在calendarApts中)-要在正确的位置显示后端数据-您需要有关会议日期和时间的信息。-此外-我建议将组件拆分为较小的组件您是否有后端结构或是否需要创建它?数据正在从其他api读取?用户是否能够创建事件?