2017-04-10 143 views
8

我目前正在嘗試構建一個簡單的react-redux應用程序,該應用程序在後端有學生和校園數據。 OnEnter曾經在這裏工作,但它在新的react-router中不存在。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''的'React'。 –

+0

偉大的解決方案! –

+0

return 在tsx中無效。 JSX元素類型「this.props.component」沒有任何構造或調用簽名。 – XGreen