Есть компонент, который получает данных из глобального state. В нем есть фильтрация и сортировка. Далее передает кладет эти данные в свой state и передает на render в другой компонент вместе с handlerom сортировки. Проблема в том, что при сортировки данные сортируются, добавляются в state, но нет перерендера. Но если что ввести в строку для фильтрации перерендер произойдет полностью (фильтрация + сортировка). Не могу понять, как пофиксить.
search.tsx (сам компонент)
interface ISearchInput{
dataVisiavble: dataType[]
}
const PageSize = 10
const SearchInput:React.FC<ISearchInput> = (dataVisiavble) =>{
const [searchText, setSearchText] = useState('')
const [data, setData] = useState<dataType[]>(dataVisiavble.dataVisiavble)
const onChangeHandler = (e:any)=> {
setSearchText(e.target.value)
/*line.id.toString().toLowerCase().includes(searchText.toLowerCase()) ||*/
const filteredData = dataVisiavble.dataVisiavble.filter(line =>{
return line.id.toString().toLowerCase().includes(searchText.toLowerCase()) ||
line.title.toLowerCase().includes(searchText.toLowerCase()) ||
line.body.toLowerCase().includes(searchText.toLowerCase())
})
setData(filteredData)
}
const sorted = (massive:dataType[],name:string,mode:boolean) =>{
switch(name){
case 'id':
if(mode){
return massive.sort((a, b) => a.id > b.id ? 1 : -1)
}
else{
return massive.sort((a, b) => a.id < b.id ? 1 : -1)
};
case 'title':
if(mode){
return massive.sort((a, b) => a.title > b.title ? 1 : -1)
}
else{
return massive.sort((a, b) => a.title < b.title ? 1 : -1)
}
case 'body':
if(mode){
return massive.sort((a, b) => a.body > b.body ? 1 : -1)
}
else{
return massive.sort((a, b) => a.body < b.body ? 1 : -1)
}
default:
return massive
}
}
const sortedHandler = (e:any) =>{
if(e.target.classList.contains("fa")){
e.target.classList.toggle('rotate')
if(e.target.classList.contains("id")){
const tmp = sorted(data,'id',e.target.classList.contains('rotate'))
setData(tmp)
console.log("seted DATA", data)
}
if(e.target.classList.contains("title")){
const tmp = sorted(data,'title',e.target.classList.contains('rotate'))
setData(tmp)
console.log("seted DATA", data)
}
if(e.target.classList.contains("body")){
const tmp = sorted(data,'body',e.target.classList.contains('rotate'))
setData(tmp)
console.log("seted DATA", data)
}
}
}
return(
<div className="mainContainer">
<div className="container">
<div className="row">
<div className="col-md-6 mainSearcher">
<input
type='text'
name='searchText'
onChange={onChangeHandler}
className = "searched"
placeholder='Поиск'
>
</input>
</div>
</div>
</div>
<div className='container'>
<div className="row">
<Table dataVisible={data} sortedHandler={sortedHandler}/>
</div>
</div>
</div>
)
}
table.tsx (компонент для прорисовки)
const PageSize = 10
interface ITable{
dataVisible:dataType[],
sortedHandler:any
}
const Table:React.FC<ITable> = ({dataVisible,sortedHandler}) =>{
const [currentPage , setCurrentPage] = useState(0)
return(
<div className="container">
<div className="row">
<div className="col-md-12 tableMain">
<table className='table'>
<thead>
<tr>
<th scope='col'>
<div className="thContainer" >
<span >ID</span>
<i className="fa fa-angle-down id" aria-hidden="false" onClick={sortedHandler}></i>
</div>
</th>
<th scope='col'>
<div className="thContainer" >
<span>Заголовок</span>
<i className="fa fa-angle-down title" aria-hidden="true" onClick={sortedHandler}></i>
</div>
</th>
<th scope='col'>
<div className="thContainer">
<span>Описание</span>
<i className="fa fa-angle-down body" aria-hidden="true" onClick={sortedHandler}></i>
</div>
</th>
</tr>
</thead>
<tbody>
{dataVisible.slice(currentPage * 10 , (currentPage * 10) + 10).map((el:dataType) =>{
return(<Line line={el} ></Line>)
})}
</tbody>
</table>
</div>
</div>
<div className="row">
<div className="col-md-12 paginationMain">
<Pagination
onPageChange={(page:number,e:any) => {
setCurrentPage(page-1)
}}
totalCount={dataVisible.length}
pageSize={PageSize}
siblingCount={1}
currentPage= {currentPage}
className={''}
/>
</div>
</div>
</div>
)
}