I am creating a list of divs, which was created with map
.
function renderButtons(){ const options = [...Array(10).keys()] // returns [0,1,2...9] return _.map(options, (option)=> renderOption(option)) } function renderOption(option:number){ return ( <div className="option-container" onClick={() => setLowerContainerVisible(true)}> <img alt="" src={"./images/feedback-icons/icon-"+option.toString()+".svg"}/> {option+1} </div> ) }
this renders a list of divs, and I was able to change each div background, when hover, like this:
.option-container{ width: 76px; height: 100px; background-color: #7777ff; display: flex; } .option-container:hover{ background-color: #adadf3; }
I wish to be able to click on a div, and change its background color to white. everything I try will change the background of all the 10 divs to white. How can I make it so only the clicked one is changed?
Advertisement
Answer
I suggest that you use renderOption
and renderButtons
as two components rather than plain functions. In the RenderButtons
component, you can use some state to maintain which item is clicked, and within RenderOption
you can control whether the background color is white or not based on wehther or not the current rendered button is the clicked option. In your .map()
method, you can use component rather than a function call <RenderOption option={option} ... />
.
See example below:
const {useState} = React; function RenderButtons() { const [clickedItem, setClickedItem] = useState(-1); return Array.from( Array(10).keys(), option => <RenderOption isClicked={clickedItem === option} option={option} setClicked={setClickedItem}/> ); } function RenderOption({isClicked, option, setClicked}) { const handleClick = () => { // setLowerContainerVisible(true) / other code to run when you click setClicked(option); // set to current option } return ( <div className={"option-container " + (isClicked ? "clicked" : "")} onClick={handleClick}> {option+1} </div> ) } ReactDOM.render(<RenderButtons />, document.body);
.option-container { width: 76px; height: 100px; background-color: #7777ff; display: flex; } .option-container.clicked, .option-container:hover { background-color: #adadf3; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script>
The className
is a little messy as it involves a ternary, to clean this up it might be worth looking into using a node package such as classnames which allows you to easily build a list of classes based on conditions.