1.withRouter作用:把不是通過路由切換過來的組件中,將react-router 的 history、location、match 三個對象傳入props對象上
默認情況下必須是經過路由匹配渲染的組件才存在this.props,才擁有路由參數,才能使用編程式導航的寫法,執行this.props.history.push('/detail')跳轉到對應路由的頁面
然而不是所有組件都直接與路由相連(通過路由跳轉到此組件)的,當這些組件需要路由參數時,使用withRouter就可以給此組件傳入路由參數,此時就可以使用this.props
2.Redirect渲染<Redirect>將導航到新位置。新位置將覆蓋歷史堆棧中的當前位置
- to: object 要重定向到的位置。 ` <Redirect to={{ pathname: '/login', search: '?utm=your+face', state: { referrer: currentLocation } }}/> - push: bool 當為true時,重定向會將新條目推入歷史記錄,而不是替換當前條目。 ` <Redirect push to="/somewhere/else"/> - from: string 要重定向的路徑名。這只能用於在<Switch>內部呈現<Redirect>時匹配位置。 有關詳細信息,請參閱<Switch children>。https://reacttraining.com/web/api/Switch/children-node ` <Switch> <Redirect from='/old-path' to='/new-path'/> <Route path='/new-path' component={Place}/> </Switch>
import React, { Component } from "react";
import {
BrowserRouter as Router,
Route,
Link,
Redirect,
withRouter
} from "react-router-dom";
////////////////////////////////////////////////////////////
// 1. Click the public page
// 2. Click the protected page
// 3. Log in
// 4. Click the back button, note the URL each time
function AuthExample() {
return (
<Router>
<div>
<AuthButton />
<ul>
<li>
<Link to="/public">Public Page</Link>
</li>
<li>
<Link to="/protected">Protected Page</Link>
</li>
</ul>
<Route path="/public" component={Public} />
<Route path="/login" component={Login} />
<PrivateRoute path="/protected" component={Protected} />
</div>
</Router>
);
}
/*登錄控制*/
const fakeAuth = {
isAuthenticated: false,
authenticate(cb) {//登錄授權
this.isAuthenticated = true;
setTimeout(cb, 100); // fake async
},
signout(cb) {//退出登錄
this.isAuthenticated = false;
setTimeout(cb, 100);
}
};
/*登錄成功組件*/
const AuthButton = withRouter(
/*withRouter作用:把不是通過路由切換過來的組件中,將react-router 的 history、location、match 三個對象傳入props對象上*/
({ history,location,match }) =>{
// console.log(history);
// console.log(location);
// console.log(match);
return fakeAuth.isAuthenticated ? (//已登錄認證就顯示下面的組件
<p>
Welcome!{" "}
<button
onClick={() => {//退出按鈕
fakeAuth.signout(() => history.push("/"));
}}
>
Sign out
</button>
</p>
) : (//沒有登錄顯示下面的組件
<p>You are not logged in.</p>
)
}
);
/*重定向路由組件,返回的是一個Route路由*/
function PrivateRoute({ component: Component, ...rest }) {
return (
<Route
{...rest}
render={props =>
fakeAuth.isAuthenticated ? (
<Component {...props} />
) : (//沒有登錄就顯示下面的路由匹配到登錄組件
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
/>
);
}
/*公共頁面無需登錄就能訪問*/
function Public() {
return <h3>Public</h3>;
}
/*登錄之后訪問的組件*/
function Protected() {
return <h3>Protected</h3>;
}
/*登錄組件*/
class Login extends Component {
state = { redirectToReferrer: false };//重定向狀態
login = () => {//登錄方法
fakeAuth.authenticate(() => {
this.setState({ redirectToReferrer: true });//登錄進行重定向
});
};
render() {
let { from } = this.props.location.state || { from: { pathname: "/" } };
let { redirectToReferrer } = this.state;
console.log(from);//Object {pathname: "/protected", search: "", hash: "", state: undefined, key: "0hr10n"}
if (redirectToReferrer) return <Redirect to={from} />;//登錄之后重定向到來時的這個組件
return (//如果沒有登錄就顯示這個登錄組件
<div>
<p>You must log in to view the page at {from.pathname}</p>
<button onClick={this.login}>Log in</button>
</div>
);
}
}
export default AuthExample;
轉載自https://reacttraining.com/react-router/web/example/auth-workflow
