2

I only paste a part of my React Code here, I have an array in my State, it can be updated and added the new array from browser.

My question is I want that array can be sorted from smallest to greatest on the time values and output to console.log, when the array was updated, how can I make it sort correctly by useEffect method?

The array structure is like the following code, the other part just control the UI updating I haven’t post there because those parts do not affect that sorting function.

const [rows, setRows] = useState([ 
{time: 3, msg:”there is the first msg”},
{time: 6, msg:”2nd msg”},
{time:11, msg:”do you have any question?”}
]);
Hamada
  • 1,836
  • 3
  • 13
  • 27
Tung Lam
  • 21
  • 1
  • 4

2 Answers2

4

You can use useMemo which will sort the array only when rows changes

const [rows, setRows] = React.useState([
    { time: 3, msg: 'there is the first msg' },
    { time: 6, msg: '2nd msg' },
    { time: 11, msg: 'do you have any question?' },
]);

const sorted = React.useMemo(() => rows.slice().sort((a, b) => a.time - b.time), [rows]);

console.log(sorted);

but in most cases react is very fast and you can sort the array every render and don't worry about performance

const sorted = rows.slice().sort((a, b) => a.time - b.time);
Nikita Madeev
  • 4,284
  • 9
  • 20
1

You can use useEffect and add rows in its dependencies array, so it'll watch whenever rows is updated. There are two ways to achieve this:

  1. Create a new state variable to save the sorted array
const [sortedRows, setSortedRows] = useState([])
useEffect(() => {
  const _sortedRows = [...rows].sort((a, b) => a.time - b.time); // as sort mutates the array, thats why created new array through spread operator
  setSortedRows(_sortedRows);
}, [rows])
  1. Use useMemo hook:
const sortedRows = React.useMemo(() => [...rows].sort((a, b) => a.time - b.time), [rows])
Muhammad Ali
  • 2,538
  • 2
  • 16
  • 21