原理解析:
1、自定义个一个PrivateRoute 组件,并传入path和component连个属性
2、在自定义组件中使用 Route 组件,判断该用户有没有登录,并展示不同的内容
3、若没有登录跳转到登录 Login组件,该组件 是一个 路由组件 在 location.state中可以找到 from 对象,以此来判断从那个页面跳转到 该Login 组件的
4、登录成功后,控制页面 跳转到 跳转到 Login组件的 组件 。(说白了就是: 从那个页面过来的再根据from对象中的链接再回去)
核心代码:
import React, { PropTypes }
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
const
AuthExample
= ()
=> (
<
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(({
history })
=> (
fakeAuth.isAuthenticated
? (
<
p>
Welcome! <
button
onClick
=
{()
=> {
fakeAuth.
signout(()
=> history.
push(
'/'))
}
}>Sign out</
button>
</
p>
)
: (
<
p>You are not logged in.</
p>
)
))
const
PrivateRoute
= ({ component:
Component,
...
rest })
=> {
return (
<
Route
{...rest
}
render
=
{
props
=> (
fakeAuth.isAuthenticated
? (
<
Component
{...props
} />
)
: (
<
Redirect
to
={{
pathname:
'/login',
state: { from: props.location }
}
} />
)
)
} />
)
}
const
Public
= ()
=> <
h3>Public</
h3>
const
Protected
= ()
=> <
h3>Protected</
h3>
class
Login
extends
React.
Component {
state
= {
redirectToReferrer:
false
}
login
= ()
=> {
fakeAuth.
authenticate(()
=> {
this.
setState({ redirectToReferrer:
true })
})
}
render() {
console.
log(
this.props.location.state)
const { from }
=
this.props.location.state
|| { from: { pathname:
'/' } }
const { redirectToReferrer }
=
this.state
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