How to add a class name in every row without effect the rest of the rows
import React, { useState } from 'react'; import './testEfect.css'; const Test = () => { const arrayTest = [ { name: '11', id: '11' }, { name: '22', id: '22' }, { name: '33', id: '33' }, ] const [state, setState] = useState(false); const handleClick = (event) => { const newState = event; setState(state ? false : true); } return ( <div className="App"> {arrayTest.map((x, index) => { return ( <ul key={index} className={state ? 'deletEfect' : ''}> <li id={x.id} > {x.name} <button onClick={(event) => handleClick(x.id)}>Delete</button> </li> </ul> ) })} </div> ) }
Advertisement
Answer
The problem here is that when you say the state is false; it is assuming the state is false for the whole component. It doesn’t update the row but the whole component. So, at first, you need to add a deleted property that will take a different value for each row.
So,
const arrayTest = [ { name: "11", id: "11", deleted: false }, { name: "22", id: "22", deleted: false }, { name: "33", id: "33", deleted: false } ]; const [state, setState] = useState(arrayTest); //initial state
Now, when you render, you don’t need to use that arrayTest. But you need to use the state. We won’t touch arrayTest ever again. So we use,
{state.map((x, index) => { return ( <ul key={index} className={x.deleted ? "testEfect" : ""}> <li id={x.id}> {x.name} <button onClick={(event) => handleClick(x.id)}>Delete</button> </li> </ul> ); })}
Notice we use state.map
. We also send x.id
to handleClick
function.
Why? Because we will use that id to change the deleted value of the object. So our handleClick
becomes,
const handleClick = (id) => { const newState = state.map((element) => { if (element.id === id) return Object.assign({}, element, { deleted: element.deleted ? false : true }); return element; }); setState(newState); };
This is just updating the state in an immutable way.
Here is the full codesandbox for your convenience.