AnswerBun.com

React : useEffect updates the state, but does not re-render the view

Stack Overflow Asked by Baudoin Michael on August 20, 2020

I’d like to sort through an array of objects.
But I’m stuck here for a while: when the props filterActivated changes, the state is updated (verified in the browser’s react dev tool), but there is no re-rendering.

I don’t understand why the view is not re-rendered, even when the ideasArray is getting updated.

This is my component :

import React, { useState, useEffect } from 'react'

// Components
import Idea from './Idea'

const IdeasContainer = ({ filterActivated }) => {

    const [ideasArray, setIdeasArray] = useState([]);

    useEffect(() => {
        const getIdeas = async () => {
            try {
                const response = await fetch("http://localhost:3004/api/ideas")
                const data = await response.json()
                setIdeasArray(data)
            } catch (err) {
                console.error('getIdeas error: ', err, err.stack)
            }
        }
        getIdeas();
    }, []);

    useEffect(() => {
        const sorted = (array) => {
            let newArray = array.sort(function (a, b) {
                if (filterActivated === 'scoreAsc') {
                    return a.score - b.score
                }
                else if (filterActivated === 'scoreDesc') {
                    return b.score - a.score
                }
            });
            setIdeasArray(newArray);
        }
        sorted(ideasArray);
    }, [filterActivated, ideasArray]);

    return (
        <div className="ideasContainer">
            {
                ideasArray.map((idea, index) => {
                    return <Idea key={index} dataIdea={idea} />
                })
            }
        </div>
    )
}

export default IdeasContainer;

One Answer

Firstly, your useEffect has a few issues:

Don't reference the ideasArray as a useEffect dependency if you're setting that value inside the useEffect. That will cause infinite loops because when you set the value, the `useEffect gets called again, which sets the value, which calls it again, which sets the value... and so on. If you depend on the previous value to set the new value, pass a setter function to the setIdeasArray function, for example:

useEffect(() => {
  setIdeasArray(oldValue =>
    [...oldValue].sort((a, b) => {
      if (filterActivated === "scoreAsc") {
        return a.score - b.score;
      } else if (filterActivated === "scoreDesc") {
        return b.score - a.score;
      }
    })
  );
}, [filterActivated]);

Notice how I'm also spreading the oldValue into a new array before sorting. This is because Array.sort is not reliably immutable, so in certain situations it will mutate the original data, which we do not want in React.


If state changes, there is always a re-render. React's render cycle is not the same as the DOM changing, but React will still run the component render cycle if props or state changes.

The issue you're having is due to using the index as a key for each idea. Using indexes as keys is a really bad idea.

The whole point of keys is to allow React to identify items in an array without it having to re-render them, so by using the indexes, what you're essentially saying is that the first item (always index 0) never changes. Yes, your state is re-ordered, but React sees that the keys have not changed order, so it does not change the DOM to match.

Keys need to be related to the item (such as a unique id), so that React can identify that item by something unrelated to "its position within an array".

Correct answer by JMadelaine on August 20, 2020

Add your own answers!

Related Questions

Recording using sox in c/c++

1  Asked on February 18, 2021

       

nodejs writing to JSON into a specific path

6  Asked on February 18, 2021 by c4llm3p3t3r

     

Unusual growth tempdb

0  Asked on February 18, 2021 by pablo-sanchez

       

Delphi Parse JSON

2  Asked on February 17, 2021 by stanley-mladenek

   

How to create a filter using bootstrap and jQuery

2  Asked on February 17, 2021 by jefin-winston

     

Change Canvas sizes with zoom

0  Asked on February 17, 2021 by reit-abdullah-yavuzkol

 

Is there a way to make the Loop Code make it faster?

4  Asked on February 17, 2021 by levesque-xylia

 

Using libcurl in g++

0  Asked on February 16, 2021 by marcel-kopera

   

Ask a Question

Get help from others!

© 2023 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP