Home > other >  array's value is getting reset while flipping boolean value in useState react js
array's value is getting reset while flipping boolean value in useState react js

Time:06-12

here I'm trying to insert a value in an array called itemList when the user clicks on the button. and after inserting the value, I want to flip the value of isCross. But, it reset the array at its initial value. and when I comment setIsCross(!isCross)

So why is this happening? App.js

import React, { useState, useEffect } from "react";
import { FaRegCircle, FaTimes } from "react-icons/fa";
import { BsDash } from "react-icons/bs";
import "./App.css";

import Icon from "./components/Icon";

const App = () => {
  // States declared
  const [isCross, setIsCross] = useState(true);

  // list created
  const itemList = new Array(9).fill("empty");

  // function on click
  const btnClicked = (index) => {
    if (itemList[index] === "empty") {
      itemList[index] = isCross ? "cross" : "circle";
      setIsCross(!isCross);

      console.log("Items: ", itemList);
    } else if (itemList[index] !== "empty") {
      alert("already filled...");
    }
  };

  // useEffect(() => {
  //   console.log("useEffect: ", itemList);
  // }, [isCross]);
  return (
    <div className="space-between">
      <div className="header flex">
        <div className="section">
          <FaRegCircle className="icon" />
          <span></span>
          <BsDash className="dash" />
        </div>
        <span className="divider-line"></span>
        <div className="section">
          <FaTimes className="icon" />
          <span></span>
          <BsDash className="dash" />
        </div>
        {itemList}
      </div>
      <div className="game">
        <div className="game-area">
          <div className="row-span">
            <span></span>
            <span></span>
          </div>
          <div className="col-span">
            <span></span>
            <span></span>
          </div>
        </div>
        <div className="game-box">
          {itemList.map((item, index) => (
            <div
              onClick={() => btnClicked(index)}
              key={index}
              className="icon flex"
            >
              <Icon name={item} />
            </div>
          ))}
        </div>
      </div>
      <div className="footer flex">
        <span>
          Created️ by{" "}
          <a
            href="https://anilrkhairnar.github.io/"
            rel="noopener noreferrer"
            target="_blank"
          >
            Anil Khairnar
          </a>
        </span>
      </div>
    </div>
  );
};

export default App;

Icons are coming from this file

Icon.js

import React from "react";
import { FaRegCircle, FaTimes } from "react-icons/fa";
import { BsDash } from "react-icons/bs";

const Icon = ({ name }) => {
  switch (name) {
    case "circle":
      return <FaRegCircle className="icon" />;
    case "cross":
      return <FaTimes className="icon" />;
    default:
      return <div></div>;
  }
};

export default Icon;

CodePudding user response:

I guess you don't really understand your own code. When you call set state i think your application re-renders, if you want to hold the state of the itemList then you should use useState. if you want the array to remember the value of its index then you should tell react how to store and remember its value.

CodePudding user response:

When a setState() function is called, as long as it is not explicitly excluded as dependency of your componenent's useEffect(), it will cause a re-render of your component (read more here).

This re-render is what causes your array to reset. In order to prevent this, you could make your list a state too, like so:

  // list created
  const [itemList, setItemList] = useState(new Array(9).fill("empty"));

  // function on click
  const btnClicked = (index) => {
    if (itemList[index] === "empty") {
      const newItemList = itemList.slice(); // make copy of itemList

      // update item at index and set state
      newItemList[index] = isCross ? "cross" : "circle";
      setItemList(newItemList);
      setIsCross(!isCross);

      console.log("Items: ", itemList);
    } else if (itemList[index] !== "empty") {
      alert("already filled...");
    }
  };
  • Related