Why does second state array, that has only one setState callback when axios get request happen modifies with main state

The first array is initial array with objects and if in main array an object changes and there is a difference between this objects i need to show "notSavedIcon". It looks like this

The main thing is that

My function and useEffect with a call of this function.

const getGames = async () => {
    const lsGameData = JSON.parse(localStorage.getItem('lsGameData'))
    try {
      const resGames = await axios.get(`${API_URL}`)
      if (Array.isArray(resGames.data)) {
        setGamesFromDB(resGames.data) /* <-------- This is a setState callback of initial array */
        if (!lsGameData) {
          console.log('no localstorage happen');
          setGames(resGames.data) /* <-------- This is a setState callback of main array */
          localStorage.setItem('lsGameData', JSON.stringify(resGames.data))
        } else {
          console.log('local storage exists happen');
          if (resGames.data.length > lsGameData.length) {
            console.log('resGames.data.length > lsGameData.length happen');
            resGames.data.map((resGame) => {
              if (!lsGameData.some(lsGame => lsGame._id === resGame._id)) {
                console.log('happen 1');
                setGames([...lsGameData, resGame]) /* <-------- This is a setState callback of main array */
                localStorage.setItem('lsGameData', JSON.stringify([...lsGameData, resGame]))
              }})
          } else if (resGames.data.length < lsGameData.length) {
            console.log('resGames.data.length < lsGameData.length happen')
            lsGameData.map((lsGame) => {
              if (resGames.data.some(resGame => lsGame._id === resGame._id)) {
                console.log('happen 2');
              } else {
                const indexAbsentEl = lsGameData.findIndex(el => el._id === lsGame._id)
                lsGameData.splice(indexAbsentEl, 1)
                localStorage.setItem('lsGameData', JSON.stringify(lsGameData))
                setGames(lsGameData)
              }
            })
          } else {
            console.log('resGames.data.length === lsGameData.length');
            setGames(JSON.parse(localStorage.getItem('lsGameData'))) /* <-------- This is a setState callback of main array */
          }
        }
      }
    } catch (e) {
      console.log(e)
    }
  }

useEffect that triggers to call that function

  useEffect(() => {
    if (!games.length) {
      console.log('no state length happen');
      void getGames()
    }
  }, [games])

Function that changes state of main array, its just calls in react dnd components. gamesCopy its a copy of main array

  const handleOnDropConfigGame = (gameConfigKey, item) => {
    switch (gameConfigKey) {
      case 'background':
        gamesCopy[indexOfSelectedGame].icon.gameIcon = item.backgroundImagePath
        gamesCopy[indexOfSelectedGame].config.background = item
        setGames(gamesCopy)
        localStorage.setItem('lsGameData', JSON.stringify(gamesCopy))
        break

      case 'objects':
        const objectArray = selectedGameState?.config?.objects
        objectArray.push(item)
        gamesCopy[indexOfSelectedGame].config.objects = objectArray
        setGames(gamesCopy)
        localStorage.setItem('lsGameData', JSON.stringify(gamesCopy))
        break

      case 'receivers':
        const receiverArray = selectedGameState?.config.receivers
        let receiversCount = selectedGameState?.config.amountOfReceivers
        if (receiverArray.some(someItem => someItem.receiverName === item.receiverName)){
          return null
        } else {
          receiverArray.push(item)
          receiversCount ++
          gamesCopy[indexOfSelectedGame].config.receivers = receiverArray
          gamesCopy[indexOfSelectedGame].config.amountOfReceivers = receiversCount
          setGames(gamesCopy)
          localStorage.setItem('lsGameData', JSON.stringify(gamesCopy))
        }
        break

      default:
        return null
    }
  }

Game Tabs component where notSavedGame icon must be shown.

import React, { useEffect, useState } from 'react';
import notSavedImg from '../../assets/images/gamesIcons/notSavedGame.svg'
import { isMatch, isEqual } from 'lodash';

const GamesListTabs = ({ games, gamesFromDB, filterGameList, handleSelectedGame, indexOfSelectedGame }) => {

  useEffect(() => {
    if(games.length && gamesFromDB.length) {
      console.log('games', games);
      console.log('gamesFromDb', gamesFromDB)
    }
  }, [games, gamesFromDB])

  return (
    <>
      {
        games
        ? games
          .filter(game => game.name.toLowerCase().includes(filterGameList.toLowerCase()))
          .map((game, key) => (
            <div
              className={indexOfSelectedGame === key ? 'game_tab game_tab_active' : 'game_tab'}
              onClick={() => handleSelectedGame(key)}
              key={key}
            >
              <div className="game_icon">
                <img
                  src={game.icon.gameIcon}
                  alt="icon"
                />
              </div>

              <div className="game_description">
                <div className="game_name">
                  <span>{game.name}</span>

                  {
                    !isEqual(games[key]?.config, gamesFromDB[key]?.config)
                      ? <img src={notSavedImg} className="not_saved_image" alt="Not saved" />
                      : null
                  }
                </div>
                <div className="game_hashtags">
                  {
                    game.gameHashtags.map((hashTag, key) => (
                      <span key={key} className="game_hashtag">
                        {hashTag}
                      </span>
                    ))
                  }
                </div>
              </div>
            </div>
          ))
        : null
      }
    </>
  )
}

export default GamesListTabs

I have tried this but it doesn`t help

import React, { useEffect, useState } from 'react';
import notSavedImg from '../../assets/images/gamesIcons/notSavedGame.svg'
import { isMatch, isEqual } from 'lodash';

const GamesListTabs = ({ games, gamesFromDB, filterGameList, handleSelectedGame, indexOfSelectedGame }) => {
  const [isSavedGameArray, setIsSavedGameArray] = useState([])
  const isSavedToSet = []

  useEffect(() => {
    console.log('games changed');

    games.forEach((el, idx) => {
      isSavedToSet.push({
        name: el.name,
        gameHashtags: el.gameHashtags,
        icon: el.icon,
        isEqual: isEqual(games[idx]?.config, gamesFromDB[idx]?.config) ||
          isEqual(games[idx]?.config?.objects, gamesFromDB[idx]?.config?.objects) ||
          isEqual(games[idx]?.config?.receivers, gamesFromDB[idx]?.config?.receivers)
      })
    })

    setIsSavedGameArray(isSavedToSet)
  }, [games, gamesFromDB])

  useEffect(() => {
    console.log('isSavedGameArray', isSavedGameArray);
  }, [isSavedGameArray])

  useEffect(() => {
    if(games.length && gamesFromDB.length) {
      console.log('games', games);
      console.log('gamesFromDb', gamesFromDB)
    }
  }, [games, gamesFromDB])
  return (
    <>
      {
        isSavedGameArray
        ? isSavedGameArray
          .filter(game => game.name.toLowerCase().includes(filterGameList.toLowerCase()))
          .map((game, key) => (
            <div
              className={indexOfSelectedGame === key ? 'game_tab game_tab_active' : 'game_tab'}
              onClick={() => handleSelectedGame(key)}
              key={key}
            >
              <div className="game_icon">
                <img
                  src={game.icon.gameIcon}
                  alt="icon"
                />
              </div>

              <div className="game_description">
                <div className="game_name">
                  <span>{game.name}</span>

                  {
                    !game.isEqual
                      ? <img src={notSavedImg} className="not_saved_image" alt="Not saved" />
                      : null
                  }
                </div>
                <div className="game_hashtags">
                  {
                    game.gameHashtags.map((hashTag, key) => (
                      <span key={key} className="game_hashtag">
                        {hashTag}
                      </span>
                    ))
                  }
                </div>
              </div>
            </div>
          ))
        : null
      }
    </>
  )
}

export default GamesListTabs
How many English words
do you know?
Test your English vocabulary size, and measure
how many words do you know
Online Test
Powered by Examplum