React-Router - компонент повторной визуализации маршрута при изменении маршрута - PullRequest
0 голосов
/ 09 января 2019

Пожалуйста, прочитайте это правильно, прежде чем пометить как дубликат, уверяю вас, что я прочитал и перепробовал все, что все предлагают об этой проблеме на stackoverflow и github.

У меня в приложении есть маршрут, показанный ниже;

<div>
        <Header compact={this.state.compact} impersonateUser={this.impersonateUser} users={users} organisations={this.props.organisations} user={user} logOut={this.logout} />
        <div className="container">
            {user && <Route path="/" component={() => <Routes userRole={user.Role} />} />}
        </div>
    {this.props.alerts.map((alert) =>
            <AlertContainer key={alert.Id} error={alert.Error} messageTitle={alert.Error ? alert.Message : "Alert"} messageBody={alert.Error ? undefined : alert.Message} />)
        }
    </div>

Визуализация маршрута Routes отображает компонент, который включает роль пользователя и лениво загружает правильный компонент маршрутов на основе этой роли, этот компонент маршрутизации отображает переключатель для главных страниц. Упрощенно это выглядит следующим образом.

import * as React from 'react';
import LoadingPage from '../../components/sharedPages/loadingPage/LoadingPage';
import * as Loadable from 'react-loadable';

export interface RoutesProps {
    userRole: string;
}

const Routes = ({ userRole }) => {

var RoleRoutesComponent: any = null;
switch (userRole) {
    case "Admin":
        RoleRoutesComponent = Loadable({
            loader: () => import('./systemAdminRoutes/SystemAdminRoutes'),
            loading: () => <LoadingPage />
        });
        break;
    default:
        break;
}

return (
    <div>
        <RoleRoutesComponent/> 
    </div>
);

}

export default Routes;

А потом компонент маршрутов

const SystemAdminRoutes = () => {

var key = "/";

return (
    <Switch>
        <Route key={key} exact path="/" component={HomePage} />
        <Route key={key} exact path="/home" component={HomePage} />
        <Route key={key} path="/second" component={SecondPage} />
        <Route key={key} path="/third" component={ThirdPage} />
        ...
        <Route key={key} component={NotFoundPage} />
    </Switch>
);
}

export default SystemAdminRoutes;

Таким образом, проблема заключается в том, что всякий раз, когда пользователь переходит от «/» к «/ секунде» и т. Д. ... приложение перерисовывает Routes, что означает, что логика переключения ролей перезапускается, пользовательские маршруты перезагружаются и повторно отображается и состояние на страницах теряется.

Вещи, которые я пробовал;

Я пробовал это как с реагирующей загрузкой, так и с React.lazy(), и у него та же проблема. Я пытался создать классы компонентов маршрутов Предоставление всем маршрутам вниз по дереву одного и того же ключа Визуализация всех компонентов вплоть до коммутатора с путем "/", но все та же проблема. Изменение реквизита компонента Route для рендеринга. Изменение метода рендеринга основного приложения на component={Routes} и получение реквизита через redux

Должно быть, что-то не так с тем, как я выполняю рендеринг компонента основных маршрутов в компоненте приложения, но я в замешательстве, может кто-нибудь пролить свет? Также обратите внимание, что это не имеет никакого отношения к коммутатору реагирующего маршрутизатора.

РЕДАКТИРОВАТЬ: я изменил один из моих старых тестовых проектов, чтобы продемонстрировать эту ошибку, вы можете клонировать репо из https://github.com/Trackerchum/route-bug-demo - после клонирования репо просто запустите установку npm в корневом каталоге и запуске npm. Я записал это на консоль, когда Routes и SystemAdminRoutes перерисованы / перемонтированы

РЕДАКТИРОВАТЬ: я открыл вопрос об этом на GitHub, возможная ошибка

Компонент повторного рендеринга маршрута при каждом изменении пути, несмотря на путь "/"

1 Ответ

0 голосов
/ 10 января 2019

Нашел причину, по которой это происходит прямо от разработчика (кредит Тим ​​Дорр). Маршрут выполняет повторную визуализацию компонента каждый раз, потому что это анонимная функция. Это происходит дважды вниз по дереву, как в приложении, так и в маршрутах (в пределах загружаемой функции), соответственно ниже.

<Route path="/" component={() => <Routes userRole={user.Role} />} />

должно быть

<Routes userRole={user.Role} />

и

loader: () => import('./systemAdminRoutes/SystemAdminRoutes')

В основном весь мой подход нуждается в переосмыслении

...