2017-04-10 27 views
8

私は現在、バックエンドに生徒とキャンパスのデータを持つ単純なreact-reduxアプリケーションを構築しようとしています。 OnEnterはここで働いていましたが、新しい反応ルータには存在しません。React-Router v4 onEnterの置き換え

このアプリケーションは、実際の各コンポーネントでcomponentDidMountを実行する代わりに、初期データを最初に読み込もうとします。それが推奨されるアプローチですか、それとも私が気づいていない代替パターンがありますか?

/* -------------------< COMPONENT >------------------- */ 
import React from 'react'; 

import { BrowserRouter as Router, Route } from 'react-router-dom'; 
import Home from './components/Home'; 
import Students from './components/Students'; 

const Routes = ({ getInitialData }) => { 
    return (
    <Router> 
     <div> 
     <Route exact path="/" component={Home} onEnter={getInitialData} /> 
     <Route path="/students" component={Students} /> 
     <Route path="*" component={Home} /> 
     </div> 
    </Router> 
); 
}; 

/* -------------------< CONTAINER >-------------------- */ 

import { connect } from 'react-redux'; 
import receiveStudents from './reducers/student'; 
import receiveCampuses from './reducers/campus'; 

const mapState = null; 
const mapDispatch = dispatch => ({ 
    getInitialData:() => { 
    dispatch(receiveStudents()); 
    dispatch(receiveCampuses()); 
    } 
}); 

export default connect(mapState, mapDispatch)(Routes); 

答えて

12

私の現在のソリューションは、機能をレンダリングし、コンポーネントのプロパティを使用しないで余分なコードを置くことです。

<Route exact path="/" render={() => { 
    getInitialData(); 
    return <Home />; 
} } /> 
+2

ここでの問題は、それがフェッチ行うの前に '' がレンダリングされます、 'getInitialData'が非同期であればということです。あなたに迷惑をかけないで、これはv4実装の欠陥です。 –

+1

私のアプリケーションでは、データがロードされていることを示すフラグを使用し、コンポーネントでチェックします。ローディング中にインジケータが表示されているので、それほど悪くはありません – akmed0zmey

5

一つの解決策は、私は少し異なるアプローチを提案したいHOC

function preCondition(condition, WrappedComponent) { 
    return class extends Component { 
    componentWillMount{ 
      condition() 
    } 

     render() { 
      <WrappedComponent {...this.props} /> 
     } 
    } 
} 

<Route exact path="/" component={preCondition(getInitialData, Home)} /> 
+0

私はあなたのソリューションが本当に好きです!あなたはこれまでの何かの欠点を見つけましたか?完璧と思われる – Ventura

+0

素晴らしい〜!ありがとう – tcstory

+0

ここで非同期呼び出しを行うことはできますか? – user2396315

7

を使用することです。クラスの継承を使用すると、独自のルータを実装できます。

import {Redirect, Route} from 'react-router'; 



/** 
* Class representing a route that checks if user is logged in. 
* @extends Route 
*/ 
class AuthRequiredRoute extends Route{ 
    /** 
    * @example <AuthRequiredRoute path="/" component={Products}> 
    */ 
    render() { 
     // call some method/function that will validate if user is logged in 
     if(!loggedIn()){ 
      return <Redirect to="/login"></Redirect> 
     }else{ 
      return <this.props.component /> 
     } 
    } 
} 
+0

すてきな解決策!しかし、私は 'react 'から' import React'を追加しなければなりませんでした。 –

+0

すばらしい解決策! –

+0

return はtsxでは無効です。 JSX要素タイプ 'this.props.component'には、構文や呼び出しシグネチャはありません。 – XGreen