2017-10-21 139 views
0

使用react和react-router 4我想從登錄視圖發送用戶登錄後,另一個視圖。我見過其他一些問題,但是沒有任何解決方案,包括使用歷史或上下文爲我工作。反應路由器4 - 編程導航到新視圖難

const { 
    Redirect, 
    HashRouter, 
    Switch, 
    Route, 
    Link 
} = ReactRouterDOM 

const App =() => { 

    const loginToServer =() => { 
    // how do I redirect user to the home route? 

    }; 

    return (
     <div className="App"> 
     <h2>Some App</h2> 

     <HashRouter> 
      <div> 
      <Link to="/login" exact activeClassName="active">Login </Link><br/> 
      <Link to="/home" activeClassName="active">Home </Link><br/> 
      <hr/> 
      <Switch> 
       <Route path="/login" 
       render={() => <Login loginToServer = { loginToServer } /> }/> 
       <Route path="/home" component={HomeComponent} /> 
       <Route exact path="/" render={() => (<Redirect to="/login"/>)}/> 
      </Switch> 
      </div> 
     </HashRouter> 
     </div> 
    ); 
    }; 

const Login = (props) => { 
    return (
    <div> 
     <h4>Login Page</h4> 
     <p>(pretend button is a submit button for a successful login)</p> 
     <button onClick= { props.loginToServer }> login </button> 
    </div> 
)} 

const HomeComponent =() => <h4>Home page</h4> 

ReactDOM.render(<App />, document.getElementById('root')); 

上述代碼在codepen here中。希望有人能告訴我實現這個最簡單的方法。謝謝。

+0

我編輯我的答案給你,因爲在現實生活中應用的替代品,你會從比你的根'App' – Freez

回答

1

您必須使用路由器history對象來處理重定向。在你的情況下,組件App包括路由器,所以你將不得不檢索history使用ref

const App =() => { 

    let router; 

    const loginToServer =() => { 
    router.history.push('/home'); 
    }; 

    return (
    <div className="App"> 
     <h2>Some App</h2> 

     <HashRouter ref={r => router = r}> 
     {/* ... */} 
     </HashRouter> 
    </div> 
); 
}; 

您也可以從你的Login組件

<Route path="/login" component={Login}/> 
//        ^^^^^ 
//     the router will be given as prop to Login 

const Login = ({ history }) => { 
    return (
    // ... 
     <button onClick={() => history.push('/home')}> login </button> 
    // ... 
) 
} 

做重定向如果你想從一個子組件重定向(不直接連接到路由),則可以使用withRouter高階組件注入路由器。

const { withRouter } = ReactRouterDOM; 

const SubComponent = withRouter(({ history }) => (
    <div onClick={() => history.push('/somewhere')} /> 
)); 
+0

感謝Freez。任何機會,你也可以展示這將如何與應用程序一起作爲一個有狀態的,基於類的組件?應該在我的代碼中以這種方式寫下這個問題。隨着應用程序作爲一個類而不是功能,我不知道如何訪問我需要它的歷史對象。不得不說,React-Router 4對我來說是相當令人沮喪的:-( – TDB

+0

如果你的應用是一個類,使用'this'來存儲你的路由器參考文獻 ' this.router = r },' 然後你可以在任何調用'this.router.history.push(...)'的類函數中使用它。 – Freez

1

首先,您要確保處理重定向的方法可以訪問history對象,該對象作爲道具傳遞給直接Route'd到的任何組件。

看着你的代碼,你應該將loginToServer函數移動到你的Login組件上,因爲,爲什麼它應該從其他任何地方被調用呢?

然後在您Login.js文件:

loginToServer() { 
    ...handle actual login logic here... 
    // if successful 
    this.props.history.push('/home'); 
} 

編輯:你必須從一個功能組件把你Login成分的一類。

+0

我拿出了一堆邏輯從相關文件在這裏蓋了其他組件和重定向codepen 。還有新的反應和做這個沒有REDX,所以在我的登錄組件(在我的真實應用程序中是有狀態的)有驗證邏輯,然後將它傳遞給父組件,在那裏我有一個axios post函數與JWT和用戶信息進行通信從我的服務器。不知道這是否是最好的辦法。 – TDB