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>
)
}
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.