javascript ReactJS:函数在return()之前被调用后无法工作,我该打到哪里?

jvlzgdj9  于 2023-05-16  发布在  Java
关注(0)|答案(1)|浏览(215)

我正在尝试在我的React项目中创建一个日历页面。当我运行该项目时,显示的唯一内容是一个小日历,其中只填充了日期和2个箭头,当按下时它们什么也不做。为了使它工作,我注解了第一个renderCalendar(),并分解了第二个。我在终端中收到警告:“无法访问的代码”。在那之后,我注解了第二个renderCalendar()并分解了第一个,它工作了。但是当我刷新页面时,只有星期几的简单日历再次显示出来。你知道如何或在哪里调用函数renderCalendar()以便从第一次运行开始工作吗?

import React from 'react';
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';

export const Calendar = () => {
  const currentDate = document.querySelector(".current-date") || {};
  let daysTag = document.querySelector(".days") || {};
  let prevNextIcon = document.querySelectorAll(".arrow");

  // getting new date, current year and month
  let date = new Date();
  let currYear = date.getFullYear();
  let currMonth = date.getMonth();

  const months = ["January", "February", "March", "April",
                  "May", "June","July", "August", "September",
                  "October", "November", "December"];

  const renderCalendar = () => {
    //get last date of month
    let firstDayofMonth = new Date(currYear, currMonth, 1).getDay();
    let lastDateofMonth = new Date(currYear, currMonth + 1, 0).getDate();
    let lastDayofMonth = new Date(currYear, currMonth, lastDateofMonth).getDay();
    let lastDateofLastMonth = new Date(currYear, currMonth, 0).getDate();
    let liTag= "";

    for (let i = firstDayofMonth; i > 0; i--) {
      liTag += `<li class= "inactive">${lastDateofLastMonth - i + 1}</li>`;
    };

    for(let i = 1; i<= lastDateofMonth; i++) {
      let isToday = i === date.getDate() && currMonth === new Date().getMonth()
                    &&  currYear === new Date().getFullYear() ? "active" : "";
      liTag += `<li class="${isToday}">${i}</li>`;
    };

    for(let i = lastDayofMonth; i<= 5; i++) {
      liTag += `<li class= "inactive">${i - lastDayofMonth + 1}</li>`;
    };

    // month and year
    currentDate.innerText = `${months[currMonth]} ${currYear}`;
    daysTag.innerHTML = liTag;    
  };
  renderCalendar();     //<------------------------------------------------------------1st

  prevNextIcon.forEach ( icon => {
    icon.addEventListener("click", () => {
      currMonth = icon.id === "prev" ? currMonth - 1 : currMonth + 1;
      
      if(currMonth < 0 || currMonth > 11) {
        date = new Date(currYear, currMonth);
        currYear = date.getFullYear();
        currMonth = date.getMonth();
      }
      else {
        date = new Date();
      };
      renderCalendar();
    });
  });

  return (
    <div className="auth flexContainer">
      <h1>Calendar</h1>
      <div className="wrapper">
        <header>
          <p className="current-date">May</p>
          <div className="icons">
            <ArrowBackIosIcon id="prev" className="arrow"/>
            <ArrowForwardIosIcon id="next" className="arrow"/>
          </div>
        </header>
        <div className="calendar">
          <ul className="weeks">
            <li>Sunday</li>
            <li>Monday</li>
            <li>Tuesday</li>
            <li>Wednesday</li>
            <li>Thursday</li>
            <li>Friday</li>
            <li>Saturday</li>
          </ul>
          <ul className="days"></ul>
        </div>
      </div>
    </div>
    );    
    //renderCalendar();     // <-----------------------------------------------------------2nd
}

你知道如何或在哪里调用函数renderCalendar()以便从第一次运行开始工作吗?

bweufnob

bweufnob1#

我必须说,这可能是更好的方式来渲染日历,并设计这个组件,这似乎过于复杂,我认为没有必要在这种情况下使用querySelectors,在react中,你可以使用refs代替。说到这里,您可以设置一个标志状态,如:

const [renderedCalendar,setRenderedCalendar]=useState(false)

然后在useEffect中调用renderCalendar,如下所示:

useEffect(()=>{

renderCalendar()

[renderCalendar]

然后在renderCalendar的末尾添加setRenderedCalendar(true)
然后在返回中进行条件渲染:

{renderedCalendar&&  <div className="auth flexContainer">....etc}

我建议您将此renderCalendar函数 Package 到useCallback中。

相关问题