1

i try to convert array of date to array of month in react

import React, {useEffect, useState} from 'react';
import {Line} from 'react-chartjs-2';
import moment from "moment";
const LinkChart = () => {
const link = [
"2021-01-19T18:11:33.383Z", 
"2021-03-19T18:11:40.617Z", 
"2021-04-19T18:11:47.894Z", 
"2021-05-19T18:11:53.305Z", 
"2021-06-19T18:11:55.341Z", 
"2021-07-19T18:11:59.325Z", 
"2021-07-20T07:05:29.877Z", 
"2021-07-21T09:02:08.691Z"]
    const [clicks,] = useState(link.clicks);
    const [clickDate,setClickDate] = useState([]);
    const [month,setMonth] = useState([]);


    useEffect(()=>{
            setClickDate(link.clicksDate);

            clickDate.map((l,index)=>{
                let months = []
                const convertedDateToMonths = moment(l).format('MMM');
                months.push(convertedDateToMonths) 
                return setMonth(months);
            })
    },[link,clickDate])
    
    return <>

    </>
}

export default LinkChart;

when i push convertedDateToMonths to array every time i rewrite month in output i got only 1 month when i do console.log(month) what i do wrong ?

2
  • 3
    You want setMonth(clickDate.map(l => moment(l).format('MMM'))) instead of most of your code Commented Jul 21, 2021 at 9:42
  • @CherryDT thanks you very much it help me very well Commented Jul 21, 2021 at 9:45

4 Answers 4

1

You need to call the setMonth function with the updated table and not on each .map loop. So just process the links with a simple map to get the list of months and call setMonth with the result of it:

const LinkChart = () => {
  const LINKS = [
    "2021-01-19T18:11:33.383Z",
    "2021-03-19T18:11:40.617Z",
    "2021-04-19T18:11:47.894Z",
    "2021-05-19T18:11:53.305Z",
    "2021-06-19T18:11:55.341Z",
    "2021-07-19T18:11:59.325Z",
    "2021-07-20T07:05:29.877Z",
    "2021-07-21T09:02:08.691Z"
  ];
  const [months, setMonths] = useState([]);

  useEffect(() => {
    setMonths(
      LINKS.map((l) => {
        return moment(l).format("MMM");
      })
    );
  }, [LINKS]);

  // ...
};

Edit modern-waterfall-c20vi

Sign up to request clarification or add additional context in comments.

Comments

1

I'm just correcting couple things to optimize from existing answer. LINKS is a constant and doesn't have to be within the component. No useEffect needed as adding the LINKS as dependency will add unnecessary re-renders (Object.is comparison on Array). Use a lazy state initialization (this assumes that the LINK is static as per your code. If its dynamic from props, then you need to watch out for re-renders)

If LINKS is static:

const LINKS = [
    "2021-01-19T18:11:33.383Z",
    "2021-03-19T18:11:40.617Z",
    "2021-04-19T18:11:47.894Z",
    "2021-05-19T18:11:53.305Z",
    "2021-06-19T18:11:55.341Z",
    "2021-07-19T18:11:59.325Z",
    "2021-07-20T07:05:29.877Z",
    "2021-07-21T09:02:08.691Z"   ]; 

const LinkChart = () => {
const [months, setMonths] = useState(() => LINKS.map((link) => moment(link).format("MMM")));
.
.
.// rest of your code
};

If LINK is dynamic:(assuming as a prop)

const LinkChart = ({links}) => {
  const allLinkMonths = links.map((link) => moment(link).format("MMM"));
  const [months, setMonths] = useState(allLinkMonths);

  useEffect(() => {
   // write a method to check if months modified. Not using array dependency as its a complicated dependency
   if(isLinkMonthsChanged(months, allLinkMonths)){
     setMonths(allLinkMonths);
   }
  });
.
.
.// rest of your code
};

1 Comment

thank you very much it's really help to me
1

What's wrong with your code:

  • You're redeclaring months on every iteration of map to an empty array.
  • You're using map to iterate an array and not create a new one (use forEach or classic for for your push-on-every-iteration approach).

How I would implement the function:

const getMonthsFromLinks(links) {
  return links.map((link) => moment(link).format('MMM'));
}

Set months in your component

const monthsList = getMonthsFromLinks(LINKS);
setMonths(monthsList);

Comments

0

you're re-initiate the month every loop. It's become empty array every loop and only save the last month only in the end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.