I had a technical interview. My code works according to the instructions but I want to know how I could have optimized it by using the Id's and using a single function instead of three.
Below is a traffic light instructions:
If a circle is white, when that circle is clicked, it should light up with the appropriate color. (Top = red, middle = yellow, bottom = green)
If a circle is already lit, when clicked again, it should go back to white.
Only one light can be lit at a time. If a light is already lit and you click on another white circle, the previously lit light should become unlit, and the clicked light should turn the appropriate color.
code I want to optimize:
I currently have 3 functions I would like to condense into one.
toggleRed
toggleYellow
andtoggleGreen
. Each block of code is nearly identical.I also wonder if there is a better way to go about using state to keep track of what light is toggled on. currently, I have 3 different useStates to keep track of each color. I feel like there was a better way for me to handle this problem.
My working code:
import "./styles.css";
import React, { useState } from "react";
export default function App() {
const [litRed, setLitRed] = useState("white");
const [litYellow, setLitYellow] = useState("white");
const [litGreen, setLitGreen] = useState("white");
const toggleRed = (e) => {
if (litRed == "white") {
setLitRed("red");
setLitYellow("white");
setLitGreen("white");
} else {
setLitRed("white");
setLitYellow("white");
setLitGreen("white");
}
};
//setLitYellow("yellow")
const toggleYellow = (e) => {
};
//setLitGreen("green")
const toggleGreen = (e) => {
};
return (
<div className="App">
<div id="traffic-light">
<button
id="top"
style={{ backgroundColor: litRed }}
onClick={toggleRed}
/>
<button
id="middle"
style={{ backgroundColor: litYellow }}
onClick={toggleYellow}
/>
<button
id="bottom"
style={{ backgroundColor: litGreen }}
onClick={toggleGreen}
/>
</div>
</div>
);
}
CodePudding user response:
I think you can use a state to store the index of the current lit light instead of using 3 state.
import "./styles.css";
import React, { useState } from "react";
export default function App() {
const [litPos, setLitPos] = useState(-1);
return (
<div className="App">
<div id="traffic-light">
<button
id="top"
style={{ backgroundColor: litPos === 0 ? 'red' : 'white' }}
onClick={() => setLitPos(litPos === 0 ? -1 : 0)}
/>
<button
id="middle"
style={{ backgroundColor: litPos === 1 ? 'yellow' : 'white' }}
onClick={() => setLitPos(litPos === 1 ? -1 : 1)}
/>
<button
id="bottom"
style={{ backgroundColor: litPos === 2 ? 'green' : 'white' }}
onClick={() => setLitPos(litPos === 2 ? -1 : 2)}
/>
</div>
</div>
);
}
useState(-1)
indicating no light is lit yet. The litPos
is used to indicate which light is on. 0 is for red, 1 is for yellow, and 2 is for green.
If you click the red light (pos 0), it will check the current listPos
.
litPos === 0 ? -1 : 0
If the current litPos is 0, it means the right light is on, so we need to turn it of by setting it back to -1, otherwise, we turn it on by setting it to 0. It also applies to the other light.
For the background color, we just need to change the background color based on the current litPos
, which light is on right now.
backgroundColor: litPos === 0 ? 'red' : 'white'
CodePudding user response:
I would use an anonymous function in the onClick and pass the color as a string to the function.
<button
id="top"
style={{ backgroundColor: litRed }}
onClick={()=>toggle("red")}
/>
And then you can have the toggle function slightly simplified to look something like this:
const toggle = (color) => {
if(color === "red"){
if (litRed == "white") {
setLitRed("red");
} else {
setLitRed("white");
}
setLitYellow("white");
setLitGreen("white");
}
//Code for yellow and red
};
Additionally, for code clarity, you could put "white","red","yellow", and "green" in a const object, similar to enums in other languages.
const Direction = {
WHITE: 'WHITE',
... };