I am changing the sort order and setting state in that order but it does not get automatically re-rendered. In the function sortVal(), I've set state setAllQues(sortArr1) which actually sets allQues array to sortArr1 which should get rendered.However, if I click on sorting button('Latest', 'A-Z', 'Z-A', or 'Oldest ') and I console log it, the array allQues is perfectly sorted but doesn't get re-rendered.
const TopQuestions = () => {
const [allQues, setAllQues] = useState(null);
const [sortWay, setSortWay] = useState('Latest');
//const [sortArr, setSortArr] = useState([]);
const format1 = 'YYYY-MM-DD HH:mm:ss';
let sortArr1 = [];
useEffect(() => {
fetch('http://localhost:4000/questions')
.then(res => {
return res.json();
})
.then(data => {
if (sortWay === 'Latest') {
data.sort((a, b) => b.sortOrder - a.sortOrder);
}
setAllQues(data);
});
}, []);
const sortVal = val => {
let sortArr1 = allQues;
console.log(sortArr1, 'sortArr1');
if (val === 'Latest') {
sortArr1 && sortArr1.sort((a, b) => b.sortOrder - a.sortOrder);
setAllQues(sortArr1);
} else if (val === 'AZ') {
sortArr1 && sortArr1.sort((a, b) => a.ques.localeCompare(b.ques));
setAllQues(sortArr1);
} else if (val === 'ZA') {
sortArr1 && sortArr1.sort((a, b) => b.ques.localeCompare(a.ques));
setAllQues(sortArr1);
} else if (val === 'Oldest') {
sortArr1 && sortArr1.sort((a, b) => a.sortOrder - b.sortOrder);
setAllQues(sortArr1);
}
console.log(allQues, 'allQues');
};
return (
<div className='mx-56 pt-16 border-l-2'>
<div className='px-4'>
<div className='flex justify-between'>
<div className=''>
<h1 className='text-3xl text-left mb-6 '>Top Questions</h1>
</div>
<div className='flex mb-6'>
<div className=' transition duration-300 ease-out border-2 border-r-0 border-gray-1050 px-2 py-1 hover:bg-gray-200 '>
<button
onClick={() => {
sortVal('Latest');
}}
className='text-gray-1150'
>
Latest
</button>
</div>
<div className=' transition duration-300 ease-out border-2 border-r-0 border-gray-1050 px-2 py-1 hover:bg-gray-200'>
<button
onClick={() => {
sortVal('AZ');
}}
className='text-gray-1150'
>
A-Z
</button>
</div>
<div className=' transition duration-300 ease-out border-2 border-r-0 border-gray-1050 px-2 py-1 hover:bg-gray-200 '>
<button
onClick={() => {
sortVal('ZA');
}}
className='text-gray-1150'
>
Z-A
</button>
</div>
<div className=' transition duration-300 ease-out border-2 border-gray-1050 px-2 py-1 hover:bg-gray-200 '>
<button
onClick={() => {
sortVal('Oldest');
}}
className='text-gray-1150'
>
Oldest
</button>
</div>
</div>
</div>
{allQues &&
allQues
.filter(allQue => (allQue.ques, allQue.author, allQue.dateTime))
.map(allQue => (
<EachQuestion
id={allQue.id}
ques={allQue.ques}
quesBrief={allQue.quesBrief}
author={allQue.author}
dateTime={allQue.dateTime}
hashes={allQue.hashes}
/>
))}
</div>
</div>
);
};
export default TopQuestions;
CodePudding user response:
Don't directly sort sortArr1, first of all, make its copy and then sort that copy and then set sorted array into the state.
you can copy array as below:
let copiedArr = [...sortArr1];
copiedArr.sort(sortFn);
setSortArr1(copiedArr);
CodePudding user response:
maybe you can try put allQues
state on the array dependencies of second useEffect parameter, because it make watch the state which is allQues, then when allQues
changed so component do side effect on first parameter of useEffect()
useEffect(() => {
fetch('http://localhost:4000/questions')
.then(res => {
return res.json();
})
.then(data => {
if (sortWay === 'Latest') {
data.sort((a, b) => b.sortOrder - a.sortOrder);
}
setAllQues(data);
});
}, [allQues]);