Не выполняется сортировка таблицы

Таблица написана на react. Ситуация такая, есть таблица в отдельном файле с таким кодом

const Table = ({ titleMassive, tableItems, sortData }) => {
return (
    <table className={s.table}>
        <thead>
            <tr className={s.title__list}>
                {titleMassive.map(i => {
                    return <th key={i.id} onClick={() => sortData(i.method)}>
                        <div className={s.title}>
                            {i.method}
                            <span className={i.arrow ? s.title__icon__up : 
                            s.title__icon__down}></span>
                        </div>
                    </th>
                })}
            </tr>
        </thead>
        <tbody>
            {tableItems.map(i => {
                return <tr className={s.item__list}>
                    <td className={s.item}>{i.id}</td>
                    <td className={s.item}>{i.name}</td>
                    <td className={s.item}>{i.email}</td>
                </tr>
            })}
        </tbody>

    </table>
)
}

Код сортировки

function App() {
const [page, setPage] = useState(1)
const [totlaPages, setTotalPages] = useState(50)
const [tableItems, setTableItems] = useState([])
const [isLoading, setIsLoading] = useState(false)
const refElement = useRef()
const [titleMassive, setTitleMassive] = useState([
{ id: 1, method: 'id', arrow: true },
{ id: 2, method: 'name', arrow: true },
{ id: 3, method: 'email', arrow: true },
])

Динамическая подгрузка данных

useEffect(async () => {
  return await axios.get(`http://jsonplaceholder.typicode.com/comments? 
  _limit=$10&_page=${page}`).then(res => {
    setIsLoading(true)
    setTableItems(prev => [...prev, ...res.data])
    setIsLoading(false)
  })
}, [page])

useObserver(refElement, page < totlaPages, isLoading, () => {
  setPage(page + 1)
})

const sortData = (sort) => {
const copyMassive = tableItems.concat()

setTitleMassive(prev => {
  return prev.map(i => {
    if (i.method === sort) {
      return { ...i, arrow: !i.arrow }
    } else {
      return i
    }
  })
})

const newMassive = titleMassive.map(i => {
  if (i.method === sort && i.arrow) {
    return copyMassive.sort((a, b) => a[sort] < b[sort] ? 1 : -1)
  } else if (i.method === sort && !i.arrow) {
    return copyMassive.sort((a, b) => a[sort] > b[sort] ? 1 : -1)
  }
})

setTableItems(...newMassive)
}

return (
<div className="App">
  {isLoading ? <h1>Заргрузка</h1> : <Table titleMassive={titleMassive} tableItems={tableItems} 
    sortData={sortData} />}
  <div ref={refElement} style={{ height: 30 }}></div>
</div>
)
}

В общем, в голову всё выглядит вот так, при клике, я изменяю сначала в массиве titleMassive, arrow нушного methoda на противоположное значение. Далее я прохожусь по массиву titleMassive и сравнивая значение method, с тем значением, которое пришло в функцию, если они совпадают, то выполняем сортировку, сортировка зависит от значения arrow, если она true, тогда по возрастанию, если false, то по убыванию. С id, всё работает хорошо, а на name и email ругается. Не могу найти ошибку


Ответы (1 шт):

Автор решения: KIrill CrAzY

Проблемы решил, после сортировки возвращается массив с объектами, если сортируем id, то возвращает [Array, undefined, undefined], с id всё работало, потому что первым стоит array, а не undefined но, когда сортируем name или email, возвращает [undefined, array, undefined]. В общём, чтобы решить проблему, нужно отфильтровать массив. Вот код:

const sortData = (sort) => {
const copyMassive = tableItems.concat()

setTitleMassive(prev => {
  return prev.map(i => {
    if (i.method === sort) {
      return { ...i, arrow: !i.arrow }
    } else {
      return i
    }
  })
})

const newMassive = titleMassive.map(i => {
  if (i.method === sort && i.arrow) {
    return copyMassive.sort((a, b) => a[sort] > b[sort] ? 1 : -1)
  } else if (i.method === sort && !i.arrow) {
    return copyMassive.sort((a, b) => a[sort] < b[sort] ? 1 : -1)
  } else return
}).filter(k => {
  return k !== undefined
})

setTableItems(...newMassive)
}

Можно создать собственный hook, но я пока не придумал, как это сделать

→ Ссылка