Open In App

How to create Grid Lights Using React ?

Last Updated : 19 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In this tutorial, we’ll walk through the process of building a React application that creates a 3×3 grid of cells. Users can activate these cells, turning them green, and witness the deactivation process in reverse order. This project serves as an excellent practice scenario for React interviews, covering essential concepts and best practices.

Prerequisites:

Approach to create Grid Lights using React:

  • Define the Cell component to manage individual grid cells, incorporating activation, deactivation, and styling.
  • Utilize React state, employing the useState hook for efficient order tracking during cell activation and deactivation.
  • Implement logic for activating cells, monitoring the order of activation, and triggering deactivation when all cells are activated.
  • Develop a function to handle cell deactivation in reverse order with a 300-millisecond interval.
  • Apply CSS styling for an appealing grid layout, differentiating styles for activated and non-activated cells.
  • Enhance accessibility by providing labels to cells for improved user understanding.

Steps to Create the Project:

Step 1: Set Up Your React App with Vite:

npm create vite@latest

Step 2: Navigate to the Project Directory

cd grid-lights

Step 3: Install the package dependency.

npm install

Folder Structure:

Screenshot-2024-02-16-214829

project structure

The updated dependencies in package.json file will look like:

"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
}
  • App.jsx: Main component orchestrating the grid, handling activation and deactivation logic, and rendering the grid using the Cell component.
  • App.css: Manages the styling of the application, ensuring a visually appealing and organized layout for the grid.

Javascript




// App.jsx
import "./App.css";
import { useState } from "react";
 
function Cell({ filled, onClick, isDisabled, label }) {
    return (
        <button
            type="button"
            aria-label={label}
            disabled={isDisabled}
            onClick={onClick}
            className={filled ? "cell cell-activated" : "cell"}
        />
    );
}
 
export default function App() {
    const [order, setOrder] = useState([]);
    const [isDeactivating, setIsDeactivating] = useState(false);
 
    const config = [
        [1, 1, 1],
        [1, 0, 1],
        [1, 1, 1],
    ];
 
    const deactivateCells = () => {
        setIsDeactivating(true);
        const timer = setInterval(() => {
            setOrder((origOrder) => {
                const newOrder = origOrder.slice();
                newOrder.pop();
 
                if (newOrder.length === 0) {
                    clearInterval(timer);
                    setIsDeactivating(false);
                }
 
                return newOrder;
            });
        }, 300);
    };
 
    const activateCells = (index) => {
        const newOrder = [...order, index];
        setOrder(newOrder);
        // deactivate
        if (newOrder.length === config.flat(1).filter(Boolean).length) {
            deactivateCells();
        }
    };
 
    return (
        <div className="wrapper">
            <div
                className="grid"
                style={{
                    gridTemplateColumns: `repeat(${config[0].length}, 1fr)`,
                }}
            >
                {config.flat(1).map((value, index) => {
                    return value ? (
                        <Cell
                            key={index}
                            label={`Cell ${index}`}
                            filled={order.includes(index)}
                            onClick={() => activateCells(index)}
                            isDisabled={order.includes(index) || isDeactivating}
                        />
                    ) : (
                        <span />
                    );
                })}
            </div>
        </div>
    );
}


Javascript




// main.jsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";
 
ReactDOM.createRoot(document.getElementById("root")).render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);


CSS




/* App.css */
body {
  font-family: sans-serif;
}
 
.wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 16px;
}
 
.grid {
  display: grid;
  max-width: 300px;
  width: 100%;
  padding: 20px;
  gap: 20px;
  border: 1px solid #000;
}
 
.cell {
  background-color: transparent;
  border: 1px solid #000;
  height: 0;
  padding-bottom: 100%;
}
.cell-activated {
  background-color: green;
}


Steps to run the application:

npm run dev

Output: Navigate to this URL : http://localhost:5173/.

Recording-2024-02-16-215533

output



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads