2017-04-10 37 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