Reputation: 15
I'm trying to toggle background of a div with changing className
every second based on changing the state of a data array.
As console.log(grid[0][0])
informs me, it actually changes the grid array data, but it doesn't update div
after the first iteration. [I provided props wiith <App row={5} col={10}/>
in index.js
.]
import React, { useState, useEffect } from 'react';
import './App.css';
function App(props) {
// Initializing the grid.
let grid = initializeGrid(props.row, props.col);
const [gridData, setGridData] = useState(grid);
useEffect(() => {
const interval = setInterval(() => {
setGridData(gridData => updateGrid(gridData));
}, 2000);
return () => clearInterval(interval);
}, []);
return (
<div className="container">
{gridData.reduce(function (acc, itm, idx) {
let item = itm.map((cell, index) => <div key={acc.length + index} className={cell.state ? "state-on" : "state-off"}>{acc.length + index}</div>);
return acc.concat(item);
}, [])}
</div>
);
}
function initializeGrid(row, col) {
let cell = { state: false, count: 0 }
let grid = [];
for (let y = 0; y < row; y++) {
grid.push([]);
for (let x = 0; x < col; x++) {
grid[y].push(cell);
}
}
return grid;
}
function updateGrid(grid) {
let currentState = grid[0][0].state;
currentState ? (grid[0][0] = { state: false, count: 0 }) : (grid[0][0] = { state: true, count: 0 });
console.log(grid[0][0]);
return grid;
}
export default App;
App.css
:
html, body, #root {
box-sizing: border-box;
background-color: #ffeead;
height: 100%;
padding: 10px;
margin: 0px;
}
.container {
height: 100%;
display: grid;
grid-gap: 3px;
grid-template-columns: repeat(10, 80px);
grid-template-rows: repeat(5, 80px);
justify-content: center;
align-content: center;
}
.container>div {
display: flex;
justify-content: center;
align-items: center;
font-size: 2em;
color: #ffeead;
}
.state-off {
background-color: #96ceb4;
}
.state-on {
background-color: #ff6f69;
}
Upvotes: 1
Views: 460
Reputation: 1242
You are mutating your state. Which is discouraged.
In strict mode, updateGrid
runs twice, so state
of cell will toggle twice. Hence you see no changes.
updateGrid
function should not mutate your state. It should be something like this:
function updateGrid(grid) {
let currentState = grid[0][0].state;
currentState
? (grid[0][0] = { state: false, count: 0 })
: (grid[0][0] = { state: true, count: 0 });
const grid0 = [{ ...grid[0][0], state: currentState }, ...grid[0].slice(1)];
const newGrid = [grid0, ...grid.slice(1)];
return newGrid;
}
Upvotes: 1