Say I have a list and I want to append an item to that list.
I want the recently added item to flash green for a few seconds so I could easily identify it in the existing list?
const mockdata = [
{id: 1, title: 'one'},
{id: 2, title: 'two'},
{id: 3, title: 'three'},
{id: 4, title: 'four',
{id: 5, title: 'five'}
]
export default function List() {
const [data, setData] = useState(mockdata)
const addItem = () => {
const newValue = {id: 6, title: 'six'}
setData(data => [...data, newValue])
}
return (
<>
{data.map((item) => {
return(
<div key={item.id}>
{item.title}
</div>
)})
}
<button
onClick={() => handleClick()}
>
Add Item
</button>
</>
)
}
I have tried adding an onChange to the div without success.
const handleChange = (e) => {
e.target.value.style.backgroundColor = "green"
}
CodePudding user response:
You can achieve this just by CSS,
create a class with animation and assign this class to newly added item, and set the CSS property of CSS animation to
animation-iteration-count: initial;
For brief example
.anim {
animation-name: color_change;
animation-duration: 1s;
animation-iteration-count: initial;
}
@keyframes color_change {
from {
background-color: blue;
}
to {
background-color: red;
}
}
CodePudding user response:
Thanks @Osama Malik for the CSS on this!
Because of the .map() I also needed a way to track which element was the one being added to the list.
I added a state variable to keep track of the last item added and updated that when the 'add' button is clicked:
const [lastItemAddedId, setLastItemAddedId] = useState(null)
const addItem = () => {
let newItem = {id: "newId", title: "newTitle"}
setData(data => [...data, newItem])
setLastItemAddedId(newItem.id)
}
Then I used a logical AND operator to check the lastItemAddedId against the Id of the items being rendered in .map() and apply the CSS class
{data.map((item) => {
return(
<div
key={item.id}
className={`${lastItemAddedId == item.id && 'flash'}`}
>
{item.title}
</div>
)})
}
Here is a worked example: https://codepen.io/jamesprenticez/pen/YzvyvxP