Search code examples
javascriptcssreactjsuse-statemap-function

Change background color of selected div in a map function


I've mapped an array of objects to a div. I would like to change background color of the selected div in getNext12MonthsWithYear map function with useState. Currently on click, background color of all divs is changing, however I want to change only the selected div's background color. Here is what I have done so far :

import React, { useState } from "react";

const Test = () => {
  const [monthSelected, setMonthSelected] = useState(false);

  const selectMonth = (id) => {
    monthSelected ? setMonthSelected(false) : setMonthSelected(true);
    console.log(id);
  };

  function getNext12MonthsWithYear() {
    var now = new Date();
    var month = now.getMonth();
    var year = now.getFullYear();

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

    var res = [];
    for (var i = 0; i < 12; ++i) {
      res.push({ month: names[month] + " " + year, status: -1 });
      if (++month === 12) {
        month = 0;
        ++year;
      }
    }
    return res;
  }

  let upcomingMonths = getNext12MonthsWithYear();
  //   console.log(upcomingMonths);

  return (
    <div style={{ display: "flex", flexDirection: "row" }}>
      {upcomingMonths.map((upcomingMonth, id) => {
        return (
          <div
            key={id}
            id={id}
            onClick={() => selectMonth(id)}
            style={{
              width: "50px",
              height: "50px",
              border: "1px solid black",
              backgroundColor: monthSelected ? "green" : "white",
            }}
          >
            {upcomingMonth.month}
          </div>
        );
      })}
    </div>
  );
};

export default Test;

Solution

  • Create a separate component for looping element. Complete code here

    import { useState } from "react";
    
    const NewCom = ({ id, upcomingMonth }) => {
      const [monthSelected, setMonthSelected] = useState(false);
    
      const selectMonth = (id) => {
        monthSelected ? setMonthSelected(false) : setMonthSelected(true);
        console.log(id);
      };
    
      return (
        <div
          id={id}
          onClick={() => selectMonth(id)}
          style={{
            width: "50px",
            height: "50px",
            border: "1px solid black",
            backgroundColor: monthSelected ? "green" : "white",
          }}
        >
          {upcomingMonth.month}
        </div>
      );
    };
    
    const Test = () => {
      function getNext12MonthsWithYear() {
        var now = new Date();
        var month = now.getMonth();
        var year = now.getFullYear();
    
        var names = [
          "January",
          "February",
          "March",
          "April",
          "May",
          "June",
          "July",
          "August",
          "September",
          "October",
          "November",
          "December",
        ];
    
        var res = [];
        for (var i = 0; i < 12; ++i) {
          res.push({ month: names[month] + " " + year, status: -1 });
          if (++month === 12) {
            month = 0;
            ++year;
          }
        }
        return res;
      }
    
      let upcomingMonths = getNext12MonthsWithYear();
      console.log(upcomingMonths);
    
      return (
        <div style={{ display: "flex", flexDirection: "row" }}>
          {upcomingMonths.map((upcomingMonth, id) => (
            <NewCom key={id} id={id} upcomingMonth={upcomingMonth} />
          ))}
        </div>
      );
    };
    
    export default Test;