Использование нумерации страниц в компоненте React без повторного рендеринга всего компонента
Я настроил нумерацию страниц (используя сторонний компонент) в одном из моих компонентов React. При каждом нажатии кнопки страницы эта функция выполняется:
handlePageChange= (page)=>{
history.push(`/duplicates?page=${page}`)
}
Я использую "Маршрутизатор" из "act-router-dom"и" CreateBrowserHistory"из библиотеки истории JS:
Когда компонент монтируется, я просто извлекаю параметр запроса "page" и отправляю действие Redux, которое извлекает все соответствующие данные и переводит их в состояние Redux:
componentDidMount(){
this.props.fetch(this.state.activePage)
}
"ActivePage" берется из состояния компонента:
state={
activePage: this.queryParams.page || 1
}
Все работает хорошо, с одним очень фундаментальным "недостатком": поскольку я использую history.push при каждом действии разбиения на страницы, весь компонент перемонтируется. Конечно, я могу перемещаться вперед и назад по своим "страницам" и даже добавлять их в закладки, но тот факт, что весь компонент нуждается в повторном рендеринге, кажется, подрывает одну из главных целей React: быть очень эффективным, когда он приходит манипуляциям DOM.
Есть ли способ настроить нумерацию страниц без необходимости выбирать между историей и эффективностью?
РЕДАКТИРОВАТЬ: это компонент:
import React from 'react';
import _ from "lodash";
import { connect } from 'react-redux';
import { searchAction, fetchDuplicates } from '../../actions/products';
import DuplicateProduct from './DuplicateProduct';
import Pagination from 'react-js-pagination'
import queryString from 'query-string';
import {history} from '../../routers/AppRouter';
class Duplicates extends React.Component{
queryParams= queryString.parse(this.props.location.search);
state={
activePage: this.queryParams.page || 1
}
handlePageChange= (page)=>{
history.push(`/duplicates?page=${page}`)
}
componentDidMount(){
this.props.fetch(this.state.activePage)
}
render(){
console.log(this.queryParams.page)
return(
<div>
<h1>Duplicate Titles</h1>
<p>number of pages: {this.props.numberOfPages}</p>
<Pagination
activePage={parseInt(this.state.activePage)}
itemsCountPerPage={150}
totalItemsCount={this.props.numberOfProducts}
pageRangeDisplayed={10}
onChange={this.handlePageChange}
className="pagination"
/>
<br/>
{this.props.duplicates.length>0 &&(
this.props.duplicates[0].map((duplicate_group)=>{
return (
<div key={duplicate_group[0].id}>
<DuplicateProduct duplicate_group={duplicate_group}/>
<hr/>
</div>
)
})
)
}
</div>
);
};
}
const mapStateToProps= (state)=>({
duplicates: state.products.duplicates,
numberOfPages: state.products.numberOfPages,
numberOfProducts: state.products.numberOfProducts
})
const mapDispatchToProps =(dispatch,props)=>({
fetch: (page)=> dispatch(fetchDuplicates(page))
})
export default connect(mapStateToProps, mapDispatchToProps)(Duplicates);
Это PrivateRoute:
import React from 'react';
import { connect } from 'react-redux';
import { Route, Redirect } from 'react-router-dom';
import Header from '../components/Header';
export const PrivateRoute = ({
isAuthenticated,
component: Component,
...rest
}) => (
<Route {...rest} component={(props) => (
isAuthenticated ? (
<div>
<Header />
<Component {...props} />
</div>
) : (
<Redirect to="/" />
)
)} />
);
const mapStateToProps = (state) => ({
isAuthenticated: state.auth.isLoggedIn
});
export default connect(mapStateToProps)(PrivateRoute);