web-dev-qa-db-ja.com

react-router v4で絶対パスにリダイレクトするにはどうすればよいですか?

私は巨大なDjango Webアプリを持っており、そのモジュールの1つ(「ダッシュボード」)がノードと反応で書かれています。ユーザーログインはDjangoモジュール。

反応ダッシュボードにアクセスするには、ユーザーがメインアプリにログインする必要があります。これは部分的に機能します。コードは、ブラウザーからユーザーセッションを取得し、存在する場合にのみレンダリングします。

セッションがない場合にユーザーをメインアプリのログインページにリダイレクトしたいのですが、現在の構造(およびこの血まみれのv4ルーター)でそれを行う方法がわかりません。

BrowserRouterコンポーネントでベース名を使用して、Djangoアプリのダッシュボードパスに関連するルートを使用しています。

これは私がapp.jsx用の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にリダイレクトされます。 BrowserRouterから 'basename'プロパティを削除して、後続の各ルートに追加できると思いますが、このモジュールが最終的に大きくなると、ルーティングが難しくなります。これを行うためのより良い方法はありますか?

6
Clara Daia

残念ながら、これは不可能です。ベース名を使用している場合は、hrefが作成される前に、すべてのパスのベースに追加されます。これは、次の関数を使用するhistoryメソッドとcreateBrowserHistoryメソッドのPushreplaceモジュールで発生します。

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をconstにして、それを各ルートのパスの前に追加します。

<Route />または<Redirect />ignoreBasenameオプションがないのは残念ですが、実装可能です。

4
Kyle Richardson

カイルの回答で述べたように、絶対URLを使用したり、ベース名を無視したりする必要はありません。ただし、コンポーネントのrenderメソッドからリダイレクトを実行するか「必要」な場合は、独自の超軽量の「絶対リダイレクト」コンポーネントを作成できます。これが私のものです。

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

次に、条件付きの他のコンポーネントを使用して、検証がtrueの場合にのみマウントされるようにします。

render(){ 

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

    ...

}

お役に立てれば :)

0
Davo