私のreactアプリには、ルートが重複する3つのエントリポイントがあり、メンテナンスが難しくなっています。メインアプリがメインサイトを完全に置き換えるのに十分な機能を備えているまで、2つのアプリは基本的にレガシーサイトのいくつかの場所でスタックしています。
React router 4を使用していて、すべてのルートを含むroutes.tsxファイルがあります。しかし、関数ごとにルートをグループ化してから、各アプリのルートコンポーネントを取得したいと思います。必要なもの。
現在、私のルートは次のようになっています。
const MainAppRoutes: React.SFC = (): JSX.Element =>
{
return (
<Switch>
<Route exact path='/' component={HomePage} />
<Route path='/customers' component={CustomersDisplayPage} />
<Route path='/customers/:id' component={CustomersDisplayPage} />
<Route path='/cars' component={CarDisplayPage} />
<Route path='/cars/:id' component={CarDisplayPage} />
</Switch>
);
};
しかし、私はそれを次のようにしたいと思います:
const MainAppRoutes: React.SFC = (): JSX.Element =>
{
return (
<Switch>
<Route exact path='/' component={HomePage} />
<CustomerAppRoutes />
<CarAppRoutes />
</Switch>
);
const CustomerAppRoutes: React.SFC = (): JSX.Element =>
{
return (
<Switch>
<Route path='/customers' component={CustomersDisplayPage} />
<Route path='/customers/:id' component={CustomersDisplayPage} />
</Switch>
);
};
const CarAppRoutes: React.SFC = (): JSX.Element =>
{
return (
<Switch>
<Route path='/cars' component={CarDisplayPage} />
<Route path='/cars/:id' component={CarDisplayPage} />
</Switch>
);
};
ただし、これにより、Caroutesは適切にルーティングされません。代わりにDivを使用してみましたが、それも機能しません。
別々のファイルにバレルしてから、メインファイルにマップすることができます
CustomerRoutes.js
import ...
export default [
{ path: '/customers', component: CustomersDisplayPage },
{ path: '/customers/:id', component: CustomersDisplayPage }
]
CarAppRoutes.js
import ...
export default [
{ path: '/cars', component: CarDisplayPage },
{ path: '/cars/:id', component: CarDisplayPage }
]
MainRoutes.js
import ...
import CarAppRoutes from 'wherever';
import CustomerRoutes from 'wherever';
...
<Switch>
<Route exact path='/' component={HomePage} />
{ CustomerRoutes.map(props => <Route {...props} />) }
{ CarAppRoutes.map(props => <Route {...props} />) }
</Switch>
注:以下の回答が機能するには、React v16.2.0以降およびTypeScriptv2.6.2以降)を使用している必要があります( ソース )。さらに、必要になる場合があります。これがすぐに機能しない場合は、異なるコンパイラパラメータを使用します( ここを参照 )。
React 16では、 Fragments
:
const MainAppRoutes: React.SFC = (): JSX.Element => (
<Switch>
<Route exact path='/' component={HomePage} />
<CustomerAppRoutes />
<CarAppRoutes />
</Switch>
);
const CustomerAppRoutes: React.SFC = (): JSX.Element => (
<>
<Route path='/customers' component={CustomersDisplayPage} />
<Route path='/customers/:id' component={CustomersDisplayPage} />
</>
);
const CarAppRoutes: React.SFC = (): JSX.Element => (
<>
<Route path='/cars' component={CarDisplayPage} />
<Route path='/cars/:id' component={CarDisplayPage} />
</>
);
私が現在使用している解決策は、ルートの配列を作成することです。
//routes.tsx
import * as React from 'react';
export interface IRoute { path: string, component: React.ComponentClass, exact?: boolean }
const CarRoutes: IRoute[] = [
{ path: '/cars', component: {CarDisplayPage} },
{ path: '/cars/:id', component: {CarDisplayPage} },
];
const CustomerRoutes: IRoute[] = [
{ path: '/customers', component: {CustomerDisplayPage} },
{ path: '/customers/:id', component: {CustomerDisplayPage} },
];
const AppRouting: React.SFC = (): JSX.Element =>
{
const routes = []
.concat(CarRoutes)
.concat(CustomerRoutes);
return (
<Switch>
<Route exact path='/' component={HomePage} />
{routes.map(r => <Route path={r.path} exact={r.exact===true} path={r.path} key={r.path} />)}
</Switch>
);
};
私がreact-router-5で同様の問題を解決しようとしたときに、この質問を見つけました。フラグメントは私には機能しませんでした。実際、Switchコンポーネントの実装の内部を見ると、その理由がわかります。フラグメントは依然としてreactコンポーネントですが、Switchはルートのみを子として期待します。
私の場合、回避策を使用できます。
関数コンポーネントを使用してルート配列を返します。
私は関数コンポーネントを反応コンポーネントとしてではなく関数として呼び出します。
必要に応じて、CustomerAppRoutesとCarAppRoutesに小道具を配置しても問題はありません。
const MainAppRoutes = () => (
<Switch>
<Route exact path='/' component={HomePage} />
{CustomerAppRoutes()}
{CarAppRoutes()}
</Switch>
);
const CustomerAppRoutes = () => ([
<Route path='/customers' component={CustomersDisplayPage} />,
<Route path='/customers/:id' component={CustomersDisplayPage} />
]);
const CarAppRoutes = () => ([
<Route path='/cars' component={CarDisplayPage} />,
<Route path='/cars/:id' component={CarDisplayPage} />
]);