@kablihin

Почему нет перерендера страницы после изменения state?

Есть компонент, который получает данных из глобального 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>
    )
}
  • Вопрос задан
  • 76 просмотров
Решения вопроса 1
Alexandroppolus
@Alexandroppolus
кодир
massive.sort выполняет сортировку в самом себе. Он не создает новый массив. То есть фактически в setData у тебя прилетает тот же объект, и реакт думает, что ничего не поменялось.
Создавай новый массив.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы