DEV Community

Cover image for React beautiful animation reordering the list of items
Toan Tran
Toan Tran

Posted on • Updated on

React beautiful animation reordering the list of items


Suppose you have a list of items ( it could be a product list, user ranking, or whatever). You asked to implement the upvote with React. How to make it appealing?
In the case of this article, I would demo a list of products, and there will be a button to upvote a product item.

Product list upvote

First few lines of code for a simple product list

Simple product list

Assume we are going to fetch a list of products from the server and keep it in state. When the user clicks on the upvote button, we will increase the vote by one.


  • What is going to change when the list reorder? The position of product item

getBoundingClientRect]( WebAPI provide us DOMRect of an element (which are left, top, right, bottom, x, y, width, and height properties)

Great. We have a product item's top and left. These properties are likely to change when the element goes up or down in the list.

  • How to keep the previous position of items so we can add animation when there is a change? If we can have a reference of the product list, we can trigger some action whenever there is a change. Also, we can compare the difference between the previous position and the next position

createRef and useRef come in place to help.

  • We need to have a way to intervene in between state changes to add animation. What React hooks should we use here?

useLayoutEffect to read layout from the DOM and synchronously re-render. Updates scheduled inside useLayoutEffect will be flushed synchronously before the browser has a chance to paint.

Okay, now we know how we can access the state of layout in between

  • The tricky thing here is how to make the upvoting smooth. CSS Transitions came to my mind such a solution.

transform and transition go with translate


  • Add ref to the product list with createRef


  • Create a custom hook to separate the logic

use custom hook

custom hook

  • An object to store DOMRect of every single item and a boolean ref to not running animation on the first run

To keep track of the DOMRect, we use product id. The origin key must be a not-changed unique key so that the product id would be the best in this case.

  • useLayoutEffect - the most important part


The logic here is to check every item on the list.

const previous = origins.current[key]; is the previous position of the item

const next = child.getBoundingClientRect(); is the next position of the item after list reorder

This line of code is for checking the differences. If there is a difference, we applied animation to this item.

Play animation

Using transform and transition in animation

Image description


I found an issue when scrolling a list. It causes the product element position to change. I added the code to update the item position when a scroll event trigger.


Source code

You can find all source code here: ( with React 18, Typescript )

  • faker generate sample data
  • plop for create a consistent templates for pages, components, etc

Any comments would be appreciated!!!

Discussion (1)

joshuaaron_ profile image
Josh Reynolds

Decent solution. Since updates to refs don't cause rerenders, placing it as a dependency for useLayoutEffect is pointless as this will never trigger the effect to be called again.