Как я могу перенаправить на абсолютный путь с помощью response-router v4?

У меня есть огромное веб-приложение Django, в котором один из модулей («приборная панель») написан с помощью node и react. Вход в систему осуществляется модулем Django.

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

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

Я использую базовое имя в компоненте BrowserRouter, чтобы использовать маршруты относительно пути панели инструментов в приложении django.

Вот что я придумал для JSX для app.jsx:

<BrowserRouter basename='/en/dashboard'>
    {this.state.isAuthenticated ? (
        <Paper zDepth={0} style={{ height: '100%', backgroundColor: grey900 }}>
            <div style={{height: '100%'}}>
                <Header />
                <Switch>
                    <Route exact={true} path='/' component={FirstSection}/>
                    <Route path='/first' component={FirstSection}/>
                    <Route path='/second' component={SecondSection}/>
                </Switch>
            </div>
        </Paper>
    ) : (
        <Redirect to="/en/login"/>
    )}
</BrowserRouter>

Однако на самом деле он перенаправляет на en/dashboard/en/login. Я считаю, что могу удалить свойство basename из BrowserRouter и добавить его к каждому последующему маршруту, но если этот модуль в конечном итоге станет больше, это затруднит маршрутизацию. Есть лучший способ сделать это?


person Clara Daia    schedule 19.07.2017    source источник


Ответы (3)


К сожалению, это невозможно. Если вы используете базовое имя, оно будет добавлено в базу каждого пути до создания href. Это происходит в модуле history в createBrowserHistory в методах push и replace, которые используют следующую функцию:

var createHref = function createHref(location) {
    return basename + (0, _PathUtils.createPath)(location);
};

использует метод push или replace.

Вы можете найти следующий блок кода в методе Redirect.prototype.perform:

if (push) {
  history.push(to);
} else {
  history.replace(to);
}

Вышеупомянутое можно найти в Redirect.js в модуле react-router, который модуль react-router-dom импортирует, а затем экспортирует.

Чтобы сделать то, что вы пытаетесь сделать, я бы сделал basename константой и добавил его в начало вашего пути в каждом из ваших маршрутов.

К сожалению, нет опции ignoreBasename для <Route /> или <Redirect />, хотя она реализуема.

person Kyle Richardson    schedule 19.07.2017
comment
Кстати, я смог реализовать опцию ignoreBasename с некоторыми исправлениями для history/createBrowserHistory.js и react-router/Redirect.js. Это меня заинтересовало, поэтому я подумываю о создании функции и запросе добавления в более позднюю версию. - person Kyle Richardson; 19.07.2017
comment
Любые новости? Такой вариант был бы очень полезен. - person Łukasz Zaroda; 13.09.2017
comment
Мне очень жаль, но я решил не заниматься этим дальше. Я делал это для v4 React-Router, browserRouter, который создает экземпляр модуля истории в строке №19. Чтобы избежать предупреждения в строке 77 createBrowserHistory.js, вам нужно будет добавить флаг в createBrowserHistory.js, включить его в browserRouter, а затем реализовать функцию ignoreBasename, что несложно, но вам нужно будет реплицировать изменения в разные типы маршрутизаторов, и это влияет на несколько библиотек. Я не считаю, что проблема настолько распространена, чтобы требовать внесения изменений. - person Kyle Richardson; 13.09.2017

Как упоминалось в ответе Кайла, нет возможности использовать абсолютные URL-адреса или игнорировать базовое имя; однако, если вы хотите или «нуждаетесь» в выполнении перенаправления из метода рендеринга вашего компонента, вы можете создать свой собственный сверхлегкий компонент «абсолютного перенаправления», вот мой:

import React from 'react'

class AbsoluteRedirect extends React.Component {

    constructor(props){
        super(props)
    }

    componentDidMount(){
        window.location = this.props.to
    }

    render(){
        return null
    }

}

export default AbsoluteRedirect

А затем используйте его другие компоненты с условием, чтобы он монтировался только тогда, когда ваша проверка верна.

render(){ 

    if( shouldRedirect )
        return <AbsoluteRedirect to={ anotherWebsiteURL } />

    ...

}

Надеюсь это поможет :)

person Davo    schedule 24.09.2019

Вы можете сделать это без реагирующего маршрутизатора:

window.location.pathname = '/en/login';

Для перехода на другой сайт используется:

window.location.href = 'https://stackoverflow.com';
person andruso    schedule 20.11.2020