Gigi101
Gigi101

Reputation: 191

Error when trying to show only a portion of an array at a time

I'm working on a project where I need to show the dates within a week, and have a button that allows users to see the next week. I have an array eightWeeks which are all of the dates within the next 8 weeks starting from the previous Sunday. If I console.log(newArr) within my function next(){...}, every time I press the next button, it's showing the next 7 days, but I can't get it to do that outside of that console.log(). My const shownWeek is static and is only giving me the first week. I have also tried: const shownWeek = next(eightWeeks), but that didn't work either. I would really appreciate any help or advice on how to fix this issue. Thank you!

export default function Calendar() {
const size = 7
let current = 1

function next(){
  if(current >= 1 && current < eightWeeks.length/size){
    current++
    let newArr = getWeekArray()
    //console.log(newArr)
  }
}

function getWeekArray(){
  return eightWeeks.slice(size*current - size, size*current)
}

const shownWeek = getWeekArray(eightWeeks)

return (
<div>
 <h1>{shownWeek}</h1>
<button onclick=next()>next</button>
<div>
)
}

Upvotes: 0

Views: 42

Answers (1)

Joel
Joel

Reputation: 483

Your variables shownWeek and current must be states. This state should be updated in the next() function. Here's the rewritten code that should work

import React from "react";

export default function Calendar() {
  const size = 7;
  const [current, setCurrent] = React.useState(1);
  // Dummy values
  const eightWeeks = [
    21,
    22,
    23,
    24,
    25,
    26,
    27,
    28,
    29,
    30,
    21,
    22,
    23,
    24,
    25,
    26,
    27,
    28,
    29,
    30,
    21,
    22,
    23,
    24,
    25,
    26,
    27,
    28,
    29,
    30,
    21,
    22,
    23,
    24,
    25,
    26,
    27,
    28,
    29,
    30
  ];
  const [shownWeek, setShownWeek] = React.useState(getWeekArray(current));

  function next() {
    if (current >= 1 && current < eightWeeks.length / size) {
      // Storing the old value of current as we will pass it as a parameter (incremented) to the getWeekArray() function.
      let currentValue = current;
      // Incrementing current. The setState function has a arrow function which has the current value of current and returns the incremented value of current.
      setCurrent((current) => current + 1);
      // Can't directly pass current as setState is asynchronous. So the value of current may not have updated yet.
      let newArr = getWeekArray(currentValue + 1);
      // Setting shownWeek as the returned array.
      setShownWeek(newArr);
    }
  }

  // Better to make getWeekArray as a parameterized function because current's value may not have updated when the function is called as it is asynchronous.
  function getWeekArray(weekNumber) {
    return eightWeeks.slice(size * weekNumber - size, size * weekNumber);
  }

  return (
    <div>
      <h1>{shownWeek}</h1>
      <button onClick={next}>next</button>
    </div>
  );
}

Here's a working codesandbox example: https://codesandbox.io/s/interesting-roentgen-br1vkn

Upvotes: 1

Related Questions