#javascript #reactjs #higher-order-components
#javascript #reactjs #компоненты более высокого порядка
Вопрос:
У меня есть СПЕЦИАЛЬНЫЙ компонент, который переносит все компоненты страницы. Компонент страницы имеет разбивку на страницы, когда пользователь нажимает далее, параметры маршрута меняются, и разница между параметром маршрута и состоянием сравнивается в componentDidUpdate, а затем вызывается api. Код работает без переноса HOC.
Маршруты
import React from 'react';
import { Redirect, Route, Switch, withRouter } from 'react-router-dom';
import hocWrapper from './hocWrapper'
import Dashboard from './components/screens/dashboard/Dashboard';
import Movies from './components/screens/movies/Movies';
const Routes = (props) => (
<Switch style={{ position: 'absolute' }}>
<Route exact path="/all/page:pageNumber" component={hocWrapper(Dashboard)} />
<Route exact path="/movies/page:pageNumber" component={Movies} />
</Switch>
);
export default withRouter(Routes);
Компонент-оболочка HOC
import React, { useEffect } from 'react';
import { useDispatch } from "react-redux";
import { searchTextAction } from './containers/actions/userActions'
export default function (ComposedClass) {
const ClosedRouteForUser = (props) => {
const dispatch = useDispatch();
useEffect(() => {
console.log(window.location.pathname)
if (window.location.pathname !== `/search/page1` amp;amp;
window.location.pathname.includes('details') === false) {
dispatch(searchTextAction(''))
}
}, []);
return <ComposedClass {...props} />;
};
return ClosedRouteForUser;
}
Компонент страницы
import React, { Component } from 'react'
import apiCall from '../../../services/apiCall';
import { trendingURL } from '../../../services/apiURL'
import MediaList from '../../common/MediaList'
import { withRouter } from 'react-router-dom';
class Dashboard extends Component {
state = {
dataList: [],
refresh: false,
pageNumber: this.props.match?.params amp;amp; this.props.match.params.pageNumber,
}
async componentDidMount() {
try {
if (this.props.match?.params.routedFrom) {
localStorage.setItem("routedFrom", this.props.match.params.routedFrom)
}
console.log('cd mount')
window.scrollTo(0, 0)
this.setState({ refresh: true })
let data = { page: 1, media_type: "all" }
let apiData = await apiCall(trendingURL, data)
this.setState({ dataList: apiData.results, refresh: false })
} catch (error) {
console.log(error)
}
}
async componentDidUpdate(prevProps, prevState) {
if (this.props.match.params.pageNumber !== this.state.pageNumber) {
console.log('cd updates')
let data = { page: this.props.match.params.pageNumber, media_type: "all" }
let apiData = await apiCall(trendingURL, data)
this.setState({
dataList: apiData.results,
pageNumber: this.props.match.params.pageNumber,
refresh: false
})
}
}
pageNavigate = (value) => {
window.scrollTo(0, 0)
this.setState({ pageNumber: value })
this.props.history.replace({ pathname: `/all/page${value}` })
}
previous = () => {
this.pageNavigate(parseInt(this.props.match.params.pageNumber) - 1)
}
next = () => {
this.pageNavigate(parseInt(this.props.match.params.pageNumber ?
this.props.match.params.pageNumber :
1) 1)
}
render() {
const { dataList, refresh } = this.state
return (
<MediaList
listData={dataList}
refresh={refresh}
previous={this.previous}
next={this.next}
/>
)
}
}
export default withRouter(Dashboard)