ssunsset
ssunsset

Reputation: 58

How to prevent useEffect re-rendering twice

I am working on my React skills and I would appreciate if you recommend me a better way of writing React code.

Here is a simple task I am currently working on: https://codepen.io/cjanes/pen/qBVaPZx?editors=0011

As you can see, in order to calculate the total price of the checked products, I need to get the array checkedItems. I choose to keep track of it inside a useEffect in TotalPrice component.

The problem is this: The TotalPrice component gets re-rendered twice, first with the last value, and then with the new calculated value.

How can I refactor my code so that it is more optimized?

Upvotes: 0

Views: 1385

Answers (1)

Nicholas Tower
Nicholas Tower

Reputation: 85241

My recommendation is that total should not be a state. Instead, it's just a derived value which you calculate from checkedItems. This makes it so that the total is always in sync with the items, and gets rid of the extra render from setting the total state:

const TotalPrice = ({ checkedItems }) => {
    let total = 0;
    checkedItems.forEach(item => total += item.price);

    console.log('TotalPrice component renders', 'total:', total)

    return ( 
        <>
            <p>Total Price is: {total}</p>
        </>
    );
}

If calculating the total was an expensive operation, you could memoize the calculation so you only repeat it when checkedItems changes:

const TotalPrice = ({ checkedItems }) => {
    const total = useMemo(() => {
        let sum = 0;
        checkedItems.forEach(item => sum += item.price);
        return sum;
    }, [checkedItems]);

Upvotes: 1

Related Questions