I am quite new to react and I am learning by trying to making an algorithm visualizer project. I am trying to make grid for shortest path algorithm where each node can be clicked to make a "wall". Since I have to dynamically change the grid on events, I tried to use the useState hook by react.
import './App.css';
import {useState} from "react";
const start_row = 9;
const start_col = 9;
const end_row = 20;
const end_col = 50;
function App() {
const [darkMode, setDarkMode] = useState(true);
function createNode(row, col) {
return {row,
col,
isStart: row === start_row && col === start_col,
isFinish: row === end_row && col === end_col,
isMousePressed: false,
};
}
const createGrid = (rows, cols) => {
const grid = [];
for (let row = 0; row < rows; row++) {
const currentRow = [];
for (let col = 0; col < cols; col++) {
currentRow.push(createNode(row, col));
}
grid.push(currentRow);
}
return grid;
}
const initialGrid = createGrid(30, 65);
let [grid, setGrid] = useState(initialGrid);
const handleClick = () => {
setDarkMode(!darkMode);
}
const setMode = (style) => {
let backgroundColor, textColor, buttonColor;
if (darkMode) {
backgroundColor = "black";
textColor = 'white';
buttonColor = "#303030";
} else {
backgroundColor = 'white';
textColor = 'black';
buttonColor = "#ffe291";
}
if (style === 1) {
return backgroundColor;
} else if (style === 2) {
return textColor;
} else {
return buttonColor;
}
}
const drawNode = (node) => {
if (node.isStart) {
return <img src="https://img.icons8.com/ios-glyphs/30/null/play--v1.png"/>;
}
if (node.isFinish) {
return <img src="https://img.icons8.com/ios-glyphs/30/null/finish-flag.png"/>
}
if (node.isMousePressed) {
return <div className="Wall"></div>
}
}
const nodeName = (row, col) => {
return `node ${row}-${col}`;
}
const handleMouseDown = (row, col) => {
let newGrid = grid.map((node) => {
if (node.row === row && node.col === col) {
node.isMousePressed = !node.isMousePressed;
}
return node;
});
setGrid(newGrid);
}
return (
<div className="App" style={{backgroundColor: setMode(1), color: setMode(2)}}>
<div className="header-container">
<div className="darkmode-container">
<label className="darkmode-button" style={{backgroundColor: setMode(3)}}>
<input type="checkbox" className="darkmode-input" onClick={handleClick}></input>
<span className="darkmode-toggle">
<img className="moon" src="https://img.icons8.com/sf-regular/48/null/moon-symbol.png"/>
</span>
<img className="sun" src="https://img.icons8.com/material-outlined/24/000000/smiling-sun.png"/>
</label>
</div>
<div className="header">
<header>Visualizer</header>
</div>
</div>
<div className="map-container">
<div className="map">
{grid.map((row, rowIndex) => {
return (
row.map((column, columnIndex) => {
return (
<div className={nodeName(rowIndex, columnIndex)} onClick={handleMouseDown(rowIndex, columnIndex) } >
{drawNode(grid[rowIndex][columnIndex])}
</div>
)
})
)
})}
</div>
</div>
</div>
);
}
export default App;
This is what I have so far and it simply crashes my app. The app works if I have a standalone grid variable not made by using "useState".