В моем редукторе аутентификации есть флаг isAuthenticated
, и я использую его в компоненте PrivateRoute
, но, похоже, он вообще не работает. Всякий раз, когда я go перехожу на любую защищенную страницу, а затем перехожу на sh эту страницу, меня перенаправляют на маршрут / . console.log
, который я поместил внутрь, возвращает true когда я go на защищенную страницу. IDK, откуда эта проблема.
localStorage.authToken
вместо isAuthenticated
в PrivateRoute
компонент работает нормально, как это:
{localStorage.authToken } ? (
<Component {...props} />
Для сохранения в componentDidMount
из root App.js
, я просто вызываю действие getCurrentUser
, которое возвращает текущего вошедшего в систему пользователя. Поэтому, когда я go захожу на защищенную страницу и пересылаю sh ее, я ожидаю, что вызов getCurrentUser
будет запущен и вернет зарегистрированного пользователя, но вместо этого на refre sh он перенаправит.
PrivateRoute
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)
auth Reducer
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
Приложение. js
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)
getCurrentUser action.
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" },
})
}
}
Примечание : я не использую библиотеки, такие как redux-persist
, и не хочу.