Home > Net >  Why does my date variable reset in my map
Why does my date variable reset in my map

Time:04-30

I am following this enter image description here

How do I stop resetting my date variable back to 1 at the end of every row?

CodePudding user response:

Easy answer, extract your print into another function and call it with your component's return statement. Also note that your print statement is O(n^2) so re-rendering with be a costly operation.

Code:

import { useState, useRef, useMemo } from 'react'
import type { NextPage } from 'next'
import Head from 'next/head'
import styles from '../styles/Home.module.scss'

const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
// console.log('render')

const Home: NextPage = () => {
  const today = new Date()
  const [currentMonth, setCurrentMonth] = useState(today.getMonth())
  const [currentYear, setCurrentYear] = useState(today.getFullYear())
  const calendarBodyRef = useRef<HTMLDivElement>(null)

  const rows = 6
  const cells = 7
  const firstDay = (new Date(currentYear, currentMonth)).getDay()

  // check how many days in a month code from https://dzone.com/articles/determining-number-days-month
  const daysInMonth = (iMonth: number, iYear: number) => {
    return 32 - new Date(iYear, iMonth, 32).getDate()
  }

  const renderCalendar = () => {
            let date = 1;
            return [...Array(rows).keys()].map((row) => {
            return (
              <div key={row} className={styles.row}>
                {[...Array(cells).keys()].map((cell) => {
                  if (row === 0 && cell < firstDay) {
                    return (
                      <div key={cell} className={styles.cell}></div>
                    )
                  } else if (date > daysInMonth(currentMonth, currentYear)) {
                    return
                  } else {
                    const cellText = String(date)
                    date  
                    return (
                      <div key={cell} className={styles.cell}>{cellText}</div>
                    )
                  }
                })}
 </div>
            )
          })}
  }

  return (
    <>
      <Head>
        <title>Calendar Budget App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <div className={styles.calendarWrap}>
        <h2 className={styles.monthTitle}>{months[currentMonth]} {currentYear}</h2>
        <div className={styles.daysWrap}>
          <span>Sun</span>
          <span>Mon</span>
          <span>Tue</span>
          <span>Wed</span>
          <span>Thu</span>
          <span>Fri</span>
          <span>Sat</span>
        </div>
        <div ref={calendarBodyRef} className={styles.calendarBody}>
          {renderCalendar()}
        </div>
      </div>
    </>
  )
}

export default Home

CodePudding user response:

I like michmich112's answer but unfortunatly I can't comment on it (lack of reputation)

But you can improve the render time by adding useMemo

import { useState, useRef, useMemo } from 'react'
import type { NextPage } from 'next'
import Head from 'next/head'
import styles from '../styles/Home.module.scss'

const months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
// console.log('render')

const Home: NextPage = () => {
  const today = new Date()
  const [currentMonth, setCurrentMonth] = useState(today.getMonth())
  const [currentYear, setCurrentYear] = useState(today.getFullYear())
  const calendarBodyRef = useRef<HTMLDivElement>(null)

  const rows = 6
  const cells = 7
  const firstDay = (new Date(currentYear, currentMonth)).getDay()

  // check how many days in a month code from https://dzone.com/articles/determining-number-days-month
  const daysInMonth = (iMonth: number, iYear: number) => {
    return 32 - new Date(iYear, iMonth, 32).getDate()
  }

  const renderCalendar = useMemo(() => {
            let date = 1;
            return [...Array(rows).keys()].map((row) => {
            return (
              <div key={row} className={styles.row}>
                {[...Array(cells).keys()].map((cell) => {
                  if (row === 0 && cell < firstDay) {
                    return (
                      <div key={cell} className={styles.cell}></div>
                    )
                  } else if (date > daysInMonth(currentMonth, currentYear)) {
                    return
                  } else {
                    const cellText = String(date)
                    date  
                    return (
                      <div key={cell} className={styles.cell}>{cellText}</div>
                    )
                  }
                })}
 </div>
            )
          })}
  }, [currentMonth, currentYear])

  return (
    <>
      <Head>
        <title>Calendar Budget App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <div className={styles.calendarWrap}>
        <h2 className={styles.monthTitle}>{months[currentMonth]} {currentYear}</h2>
        <div className={styles.daysWrap}>
          <span>Sun</span>
          <span>Mon</span>
          <span>Tue</span>
          <span>Wed</span>
          <span>Thu</span>
          <span>Fri</span>
          <span>Sat</span>
        </div>
        <div ref={calendarBodyRef} className={styles.calendarBody}>
          {renderCalendar()}
        </div>
      </div>
    </>
  )
}

export default Home
  • Related