При использовании react-маршрутизатора 5 с redux 7 react-маршрутизатор не сбрасывает состояние после перехода на новый маршрут

#javascript #reactjs #redux #react-router #react-router-dom

Вопрос:

Я использую следующие версии:

 `"react-router": "^5.2.0",`
`"react-router-domreact-router": "^5.2.0",`
 

Не уверен, подходит ли моя текущая настройка для React-маршрутизатора 5 или нет, до этого я использовал версию до v5.

Проблема в этом примере заключается в <Route component={withTracker(InterviewContainer)} path="/interviews/companies/:companyId" /> том, что и <Link/>

Вот мой сценарий:

  1. Домашняя страница загружается со списком ссылок на компанию
  2. Нажмите на компанию <Link /> , в которую я направляюсь /interviews/companies/:companyId
  3. Страница загружается нормально, я вижу изображения и т. Д. для этой конкретной компании
  4. Нажмите кнопку браузера Назад
  5. Нажмите на другую компанию <Link /> , которая указывает на другую компанию.
  6. Проблема: для № 5, когда страница компании загружается изначально, по какой-то причине она загружается устаревшими изображениями и данными. Другими словами, я кратко просматриваю данные и изображения предыдущей компании с шага № 2, пока мой крючок реакции не сделает новый вызов для получения данных для этого нового идентификатора компании и не перерисует браузер с правильными данными (данные для идентификатора компании, представленного в новом маршруте).

index.tsx (обратите внимание на использование BrowserRouter здесь)

 import { BrowserRouter as Router } from 'react-router-dom';
//...more code and then:

render(
    <>
        <div className="Site">
            <Provider store={store}>
                <Router>
                    <App />
                </Router>
            </Provider>
        </div>
        <Footer />
    </>,
);
 

Приложение.ts

 import { Route, RouteComponentProps, Switch } from 'react-router-dom';

...more code and then here are my routes:

<Switch>
    <Route component={withTracker(HomePageContainer)} exact path="/" />
    <Route
        path="/companies/:companyId/details"
        render={(props: RouteComponentProps<{ companyId: string }>) => (
            <CompanyDetailContainer {...props} fetchCompanyNew={fetchCompanyNew} httpRequest={Request} useFetchCompany={useFetchCompany} />
        )}
    />
    <Route component={withTracker(InterviewContainer)} path="/interviews/companies/:companyId" />
    <Route component={withTracker(About)} path="/about" />
    <Route component={withTracker(Container)} path="/" />
    <Route component={withTracker(NotFound)} path="*" />
</Switch>
 

Here is how the company Link is coded:

Note: I am using Redux State
«react-redux»: «^7.2.1»,
«redux»: «^4.0.5»,
«redux-thunk»: «^2.3.0»,

InterviewContainer.tsx (the parent that does the company fetching)

 class InterviewContainer extends Component<PropsFromRedux amp; RouteComponentProps<{ companyId: string }>> {
    componentDidMount() {
        const { fetchCompany } = this.props;
        const { companyId } = this.props.match.params;
        fetchCompany(companyId);
    }
    
    render() {
        const { company } = this.props;
        return (company amp;amp; <Interview className="ft-interview" company={company} />) || null;
    }
}

const mapState = (state: RootState) => ({
    company: state.company.company,
});

const mapDispatch = {
    fetchCompany: fetchCompanyFromJSON,
};

const connector = connect(mapState, mapDispatch);

type PropsFromRedux = ConnectedProps<typeof connector>;
export default withRouter(connect(mapState, mapDispatch)(InterviewContainer));
 

LinkItem.tsx (один из детей, предоставленных InterviewContainer и полученных компанией от InterviewContainer )

 render() {
    const { company } = this.props,
        uri = company.notInterviewed ? `companies/${company.id}/details` : `/interviews/companies/${company.id}`,
        className = `margin-top-10 margin-bottom-10 ${company.notInterviewed ? 'ft-company-not-interviewed' : ''}`;
    const link = (
        <Link className={className} id={company.id.toString()} to={uri}>
            <span id="company-name">{company.name}</span>
        </Link>
    );
}
 

Я думаю, что мне, возможно, придется сбросить состояние Redux при изменении маршрута. Я вижу, что люди в прошлом использовали LOCATION_CHANGE , но это устарело, и это константа, предоставляемая сторонними библиотеками redux, которые больше не поддерживаются. Так что не знаю, как это сделать с Redux v7

Поэтому я думаю, что мне просто нужен способ определить изменение местоположения, а затем каким-то образом обновить мой магазин react, чтобы сбросить компанию (значение company: state.company.company, не определено в моем действии redux)

Ответ №1:

Я знаю, что такие вещи могут быть обременительными. Вы пробовали перейти в состояние со ссылкой как <Link to={uri} state={...someState} /> . Затем, где бы он ни загружался, он должен повторно или сбросить реквизиты в соответствии с этим. Может быть, добавить несколько загрузчиков скелетов или логику условного рендеринга.

Комментарии:

1. Я никогда не видел, чтобы состояние проходило через <Ссылку />. Я просто вытаскиваю идентификатор компании из реквизитов маршрута this.props.match.params; и извлекаю данные компании в своем крючке React. Дело не в том, что это не повторный рендеринг, а в том, что при первоначальном рендеринге каким-то образом отображаются устаревшие данные компании. Я не вижу ничего в коде, вызывающего это, так что это должно быть что-то с react-маршрутизатором и историей браузера, это мое предположение

2. черт возьми, да. Я люблю использовать параметры и этот.реквизит.совпадение.параметры для одного и того же факта. Состояние является декларативным и не меняется при повторном отправке или даже обновлении. Иногда это может быть не лучшим решением, когда вы хотите использовать параметры или локальное состояние, чтобы сделать что-то еще со своим реквизитом. Суммировать параметры по штату каждый день.

3. Также для передачи состояния я извлек код из документации, <Link to={{ pathname: "/courses", search: "?sort=name", hash: "#the-hash", state: { fromDashboard: true } }} /> я нахожу его полезным, когда хочу, чтобы часть состояния из текущих реквизитов передавалась новому объекту истории. Я почти уверен, что <Ссылка / > — это просто история.нажмите, а <Ссылка /><Перенаправление / > — это история.замените.

4. просто мне это кажется банальным, извини. Мне не нужно делать ничего необычного, чтобы исправить эту проблему с ссылками, ИМО

5. Я должен добавить, что я использую redux. И я искал, и должен быть какой-то способ сбросить состояние redux, отличное от использования LOCATION_CHANGE , которое исходит из специальных библиотек redux-маршрутизатора, которые сейчас устарели