HomeBlogErrors / FixesFor Sale
Errors / FixesSeptember 5, 20262 min

For Sale

When Updating State Does Not Cause Component Re-rendering #### Symptoms of the Problem Your website contains several elements that you want to sort based on different criteria. However, when...

For Sale
For Sale - image 2

When Updating State Does Not Cause Component Re-rendering

Symptoms of the Problem

Your website contains several elements that you want to sort based on different criteria. However, when the data of an object is changed, the components do not re-render even though the data updates successfully.

Example Code

To illustrate the problem, consider the following code snippet:

import React, { useState } from 'react';
import { Link } from 'react-router-dom';

function SaleBody() {
    const [db, setDb] = useState([
        { img: house1, price: 46000 },
        { img: house2, price: 58000 },
        { img: house3, price: 82000 },
        { img: house4, price: 32000 },
    ]);

    const handleClick = () => {
        setDb(db.sort((a, b) => b.price - a.price));
    };

    return (
        <React.Fragment>
            <div className='sort'>
                <p>Sort By</p>
                <div className="dropdown">
                    <img id='dropdown-btn' src={dropdownIcon} />
                    <div className="dropdown-content">
                        <a onClick={handleClick} href="#">Price Ascending</a>
                        <a href="#">Price Descending</a>
                        <a href="#">Random</a>
                    </div>
                </div>
            </div>
            <div className='sale-body-item'>
                <img src={db[0].img} />
                <div className='house-text'>
                    <div className='house-text-item'>
                        <h1>For Sale</h1>
                        <p>${db[0].price}</p>
                    </div>
                    <div className='house-text-item'>
                        <h1>Adress</h1>
                        <p>Lorem Ipsum St.</p>
                    </div>
                    <div className='house-text-item'>
                        <p>3 bedrooms,</p>
                        <p>2 bathrooms,</p>
                        <p>40m2 garden</p>
                    </div>
                </div>
                <Link to='/item'><button>More Information</button></Link>
            </div>
            <div className='sale-body-item'>
                <img src={db[1].img} />
                <div className='house-text'>
                    <div className='house-text-item'>
                        <h1>For Sale</h1>
                        <p>${db[1].price}</p>
                    </div>
                    <div className='house-text-item'>
                        <h1>Adress</h1>
                        <p>Lorem Ipsum St.</p>
                    </div>
                    <div className='house-text-item'>
                        <p>3 bedrooms,</p>
                        <p>2 bathrooms,</p>
                        <p>40m2 garden</p>
                    </div>
                </div>
                <button>More Information</button>
            </div>
        </React.Fragment>
    );
}

Causes of the Problem

The issue may be related to several causes:

  1. Empty State: If the updated state is the same object or array as before, React might not consider it a change.
  2. Incorrect Data Copying: Incorrectly copying data can lead to changes not reflecting in the state.

Solutions

To solve the problem, you can use methods for deep copying data such as JSON.parse(JSON.stringify()) or using the lodash library.

Solution with lodash:

import _ from 'lodash';

const handleClick = () => {
    setDb(_.sortBy(db, ['price'], [false]));
};

Solution with JSON.stringify:

const handleClick = () => {
    setDb(JSON.parse(JSON.stringify(db.sort((a, b) => b.price - a.price))));
};

Practical Tips

  1. Use Deep Data Copying: Ensure you create a new copy of the data before updating the state.
  2. Check State After Update: Use console.log to verify if the state has indeed been updated.
  3. Use the useEffect Hook for Additional Actions: If you need to perform any actions after state update, use the useEffect hook.

SEO and Metadata

** ** ** ** **