React JS Interview Questions ( Grid Lights - GreatFrontEnd ) - Frontend Coding Interview
Table of contents
Grid Lights is a famous problem from GreatFrontend.com which has been asked in Machine Coding round of Frontend Interviews at companies like Meta, Google, Netflix, Amazon, Airbnb, etc. In this blog, I will provide the solution to the problem
Problem Statement
Build a grid of light cells where you can click on cells to activate them, turning them green. When all the cells are activated, all the cells will be deactivated one by one in the reverse order they were activated with 300ms interval in between them.
Steps:
Create a grid
Create the cell and style it with a green background color when activated.
Add click logic to activate cell when clicked.
In the click logic, when all the cells are activated, deactivate cells one by one using setInterval.
import "./styles.css";
import { useState } from "react";
const Cell = ({ filled, onClick, isDisabled, label }) => {
return (
<button
type="button"
className={filled ? "cell cell-active" : "cell"}
onClick={onClick}
disabled={isDisabled}
aria-label={label}
/>
);
};
export default function App() {
// order state for order of activated cells
const [order, setOrder] = useState([]);
const [isDeactivating, setIsDeactivating] = useState(false);
const config = [
[1, 1, 1],
[1, 0, 1],
[1, 1, 1]
];
const activateCells = (index) => {
const updatedOrder = [...order, index];
setOrder(updatedOrder);
if (updatedOrder.length === config.flat(1).filter(Boolean).length) {
// reverse the animation
deactivateCells();
}
};
const deactivateCells = () => {
setIsDeactivating(true);
const timer = setInterval(() => {
setOrder((currentOrder) => {
// create a shallow copy of the order state array
const newOrder = currentOrder.slice();
newOrder.pop();
if (newOrder.length === 0) {
clearInterval(timer);
setIsDeactivating(false);
}
return newOrder;
});
}, 300);
};
return (
<div className="wrapper">
<div
className="grid"
style={{
gridTemplateColumns: `repeat(${config[0].length}, 1fr)`
}}
>
{config
.flat(1)
.map((value, index) =>
value === 1 ? (
<Cell
key={index}
filled={order.includes(index)}
onClick={() => activateCells(index)}
isDisabled={order.includes(index) || isDeactivating}
label={`Cell ${index}`}
/>
) : (
<span />
)
)}
</div>
</div>
);
}
.wrapper {
display: flex;
justify-content: center;
align-items: center;
gap: 16px;
}
.grid {
display: grid;
max-width: 300px;
width: 100%;
gap: 16px;
border: 1px solid black;
padding: 20px;
}
.cell {
height: 0;
padding-bottom: 100%;
border: 1px solid black;
background-color: transparent;
}
.cell-active {
background-color: green;
}
That's how we solved this problem. If you didn't understand something, please do comment I will try to answer your queries in the comments.
If you liked the problem and want me to write a blog/provide solutions to similar problems, please hit the like button and share it with someone who is preparing for frontend interviews.
Like. Comment. Share.