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;
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
1 Asked on February 18, 2021
2 Asked on February 18, 2021 by princeoo7
1 Asked on February 18, 2021 by thurahtetaung
0 Asked on February 18, 2021 by pavel-fadeev
6 Asked on February 18, 2021 by c4llm3p3t3r
0 Asked on February 18, 2021 by pablo-sanchez
1 Asked on February 18, 2021 by rudi
1 Asked on February 17, 2021 by shin-yamagami
6 Asked on February 17, 2021
1 Asked on February 17, 2021 by thlik
2 Asked on February 17, 2021 by li97
1 Asked on February 17, 2021 by chris-johnson
2 Asked on February 17, 2021 by jefin-winston
4 Asked on February 17, 2021 by levesque-xylia
0 Asked on February 17, 2021
1 Asked on February 16, 2021 by trisimix
Get help from others!
Recent Answers
Recent Questions
© 2023 AnswerBun.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP