我的auth reducer中有一个isAuthenticated
标志,并且在PrivateRoute
组件中使用了它,但看起来根本没有用。每当我进入任何受保护的页面,然后刷新该页面时,都会被重定向到 / 路由。每当我进入受保护的页面时,我放入其中的console.log
都会返回true。 IDK的问题出在哪里。
localStorage.authToken
可以代替isAuthenticated
组件中的PrivateRoute
,如下所示:
{localStorage.authToken } ? (
<Component {...props} />
为持久起见,在根componentDidMount
的{{1}}中,我只是调用App.js
操作,该操作返回当前登录的用户。因此,当我进入一个受保护的页面并刷新它时,我希望getCurrentUser
调用被激发并返回登录的用户,但是刷新后,它会重定向。
私人路线
getCurrentUser
auth Reducer
import React from "react"
import { Route, Redirect } from "react-router-dom"
import { connect } from "react-redux"
const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => {
console.log(isAuthenticated)
return (
<Route
{...rest}
render={(props) =>
isAuthenticated ? (
<Component {...props} />
) : (
<Redirect to={{ pathname: "/", state: { from: props.location } }} />
)
}
/>
)
}
const mapStateToProps = (state) => {
return { isAuthenticated: state.auth.isAuthenticated }
}
export default connect(mapStateToProps)(PrivateRoute)
App.js
const initialState = {
isAuthInProgress: false,
isAuthenticated: false,
authError: null,
user: {},
isIdentifyingToken: false,
token: localStorage.getItem("authToken") || "",
}
const auth = (state = initialState, action) => {
switch (action.type) {
case "AUTH_STARTS":
return {
...state,
isAuthInProgress: true,
isAuthenticated: false,
authError: null,
}
case "AUTH_SUCCESS":
return {
...state,
isAuthInProgress: false,
authError: null,
isAuthenticated: true,
isIdentifyingToken: false,
user: action.data.user,
}
case "AUTH_ERROR":
return {
...state,
isAuthInProgress: false,
authError: action.data.error,
isAuthenticated: false,
user: {},
}
case "TOKEN_VERIFICATION_STARTS":
return {
...state,
isAuthInProgress: true,
authError: null,
isIdentifyingToken: true,
}
case "LOGOUT_USER":
return {
...state,
isAuthenticated: false,
token: localStorage.removeItem("authToken"),
user: {},
}
default:
return state
}
}
export default auth
getCurrentUser 操作。
class App extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
const authToken = localStorage.getItem("authToken")
if (authToken) {
this.props.dispatch({ type: "TOKEN_VERIFICATION_STARTS" })
this.props.dispatch(getCurrentUser(authToken))
}
}
render() {
const { isIdentifyingToken } = this.props
return (
<div>
{isIdentifyingToken ? null : (
<Router>
<Switch>
<Route exact path="/" component={LandingPage} />
<Route path="/register" component={RegistrationForm} />
<Route path="/login" component={LoginForm} />
<PrivateRoute path="/feed" component={Feed} />
<PrivateRoute path="/post/new" component={NewPostForm} />
<Route path="/post/edit/:id" component={EditForm} />
<PrivateRoute exact path="/profile/:username"component={UserProfile} />
<PrivateRoute path="/profile/:username/posts" component={UserFeed} />
<Route component={NotFoundPage} />
</Switch>
</Router>
)}
</div>
)
}
}
const mapStateToProps = (state) => ({
isIdentifyingToken: state.auth.isIdentifyingToken,
})
export default connect(mapStateToProps)(App)
注意:我没有使用export const getCurrentUser = (token) => {
return async (dispatch) => {
dispatch({ type: "AUTH_STARTS" })
try {
const res = await axios.get(`${baseUrl}/users/me`, {
headers: {
Authorization: token,
},
})
dispatch({
type: "AUTH_SUCCESS",
data: { user: res.data.user },
})
} catch (err) {
dispatch({
type: "AUTH_ERROR",
data: { error: "Something went wrong" },
})
}
}
之类的库,也不想使用。