次のreact機能コンポーネントがあり、react-routerを使用した認証に必要なルートをサポートします。
const PrivateRoute = ({ component: Component, ...rest }) => (
<Route {...rest} render={props => (
isAuthenticated() ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: {from: props.location }
}}/>
)
)}/>
)
これを機能コンポーネントからクラスコンポーネントに変換して、React.ComponentのcomponentDidMountメソッドを利用できるようにする必要があります。残念ながら、これを移行する方法を理解するのに苦労しています。そのまま使用する場合、Componentパラメーターと... restパラメーターを複製する必要がありますが、その方法はわかりません。 this.props.componentでComponentパラメーターを取得できると思いますが、...レストをプルする方法がわかりません。私はJSXとES6を初めて使用するので、ヘルプやガイダンスをいただければ幸いです。
本当に難しいことは何もありません。機能コンポーネントはrender
関数なので、次のようになります。
class PrivateRoute extends React.Component {
render() {
const {component: Component, ...rest} = this.props;
return (
<Route {...rest} render={props => (
isAuthenticated() ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: {from: props.location }
}}/>
)
)}/>
);
}
}
または、もう少し読みやすいように書かれています:
class PrivateRoute extends React.Component {
render() {
const {component: Component, ...rest} = this.props;
const renderRoute = props => {
if (isAuthenticated()) {
return (
<Component {...props} />
);
}
const to = {
pathname: '/login',
state: {from: props.location}
};
return (
<Redirect to={to} />
);
}
return (
<Route {...rest} render={renderRoute}/>
);
}
}
Route
コンポーネントを拡張することによる、すてきでクリーンなリファクタリング:
class PrivateRoute extends Route {
render() {
return isAuthenticated()
? super.render()
: <Redirect to={{
pathname: '/login',
state: {from: props.location}
}}/>;
}
}
これを使用する場合、以下のように<PrivateRoute/>s
を<Switch/>
でラップする必要があります。そうしないと、リダイレクトが重複し、ページの読み込みに失敗します。
<Router>
<Navbar/>
<SideDrawer/>
<Switch>
<Route path="/tokens" component={Login}/>
<PrivateRoute exact path="/" component={ExampleComponent}/>
<PrivateRoute path="/users" component={Users}/>
<PrivateRoute path="/software" component={Software}/>
</Switch>
</Router>