Не выполняется сортировка таблицы
Таблица написана на 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 шт):
Проблемы решил, после сортировки возвращается массив с объектами, если сортируем 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, но я пока не придумал, как это сделать