Home > Net >  React: How to highlight an item for a few seconds when it is added to a list
React: How to highlight an item for a few seconds when it is added to a list

Time:10-31

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

  • Related