为什么访问非 <PrivateRoute> 页面会清除我的 persist:polls 身份验证?
Why does visiting a non <PrivateRoute> page clear my persist:polls authentication?
我正在使用 redux-persist 来跟踪用户令牌,并使用 PrivateRoutes 来允许访问主仪表板。 persist:polls 使用 JWT 令牌存储在本地存储中。如果我只单击标记为一切都按预期工作的路由,但是一旦我单击 "Privacy Policy" 之类的非私有内容,我的本地存储 persist:polls 将被重置。
我不确定这是 PrivateRoute、redux-persist 还是其他问题?这是我的 store.js 文件:
import storage from 'redux-persist/es/storage'
import {applyMiddleware, compose, createStore} from 'redux'
import {createFilter} from 'redux-persist-transform-filter';
import {persistReducer, persistStore} from 'redux-persist'
import {routerMiddleware} from 'react-router-redux'
import thunk from 'redux-thunk';
import apiMiddleware from './middleware';
import rootReducer from './reducers'
// This is helpful: https://github.com/edy/redux-persist-transform-filter
export default (history) => {
const persistedFilter = createFilter(
'auth', ['access', 'refresh', 'username']
);
const reducer = persistReducer(
{
key: 'polls',
storage: storage,
whitelist: ['auth'],
transforms: [persistedFilter]
},
rootReducer
);
// This is used for setup here: https://github.com/zalmoxisus/redux-devtools-extension#usage
// This was copied from ds-rebuild folder.
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
// Add thunk to handle error: "Error: Actions must be plain objects. Use custom middleware for async actions."
const store = createStore(
reducer,
{},
composeEnhancers(applyMiddleware(apiMiddleware, thunk, routerMiddleware(history)))
);
persistStore(store);
return store
}
这是我的 PrivateRoute
import React from 'react'
import { Route, Redirect } from 'react-router'
import { connect } from 'react-redux'
import * as reducers from '../reducers'
const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => (
<Route {...rest} render={props => (
isAuthenticated ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}}/>
)
)}/>
);
const mapStateToProps = (state) => ({
isAuthenticated: reducers.isAuthenticated(state)
});
export default connect(mapStateToProps, null)(PrivateRoute);
最后,这是我的主要 App 路由器
function LandingApp() {
return (
<ConnectedRouter history={history}>
<Switch>
<PrivateRoute exact path="/(app|profile)" component={App}/>
<Route exact path="/" component={Theme1}/>
<Route exact path="/login" component={Login1}/>
<Route exact path="/signup" component={SignUp1}/>
<Route exact path="/privacy" component={Privacy}/>
<Route exact path="/tos" component={Terms}/>
<Route component={NotFound}/>
</Switch>
</ConnectedRouter>
)
}
export default LandingApp;
我不得不将我的路由器包裹在 PersistGate
ReactDOM.render(
<Provider store={store}>
<PersistGate persistor={persistStore(store)}>
<LandingApp/>
</PersistGate>
</Provider>, document.getElementById('root'));
我正在使用 redux-persist 来跟踪用户令牌,并使用 PrivateRoutes 来允许访问主仪表板。 persist:polls 使用 JWT 令牌存储在本地存储中。如果我只单击标记为一切都按预期工作的路由,但是一旦我单击 "Privacy Policy" 之类的非私有内容,我的本地存储 persist:polls 将被重置。
我不确定这是 PrivateRoute、redux-persist 还是其他问题?这是我的 store.js 文件:
import storage from 'redux-persist/es/storage'
import {applyMiddleware, compose, createStore} from 'redux'
import {createFilter} from 'redux-persist-transform-filter';
import {persistReducer, persistStore} from 'redux-persist'
import {routerMiddleware} from 'react-router-redux'
import thunk from 'redux-thunk';
import apiMiddleware from './middleware';
import rootReducer from './reducers'
// This is helpful: https://github.com/edy/redux-persist-transform-filter
export default (history) => {
const persistedFilter = createFilter(
'auth', ['access', 'refresh', 'username']
);
const reducer = persistReducer(
{
key: 'polls',
storage: storage,
whitelist: ['auth'],
transforms: [persistedFilter]
},
rootReducer
);
// This is used for setup here: https://github.com/zalmoxisus/redux-devtools-extension#usage
// This was copied from ds-rebuild folder.
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
// Add thunk to handle error: "Error: Actions must be plain objects. Use custom middleware for async actions."
const store = createStore(
reducer,
{},
composeEnhancers(applyMiddleware(apiMiddleware, thunk, routerMiddleware(history)))
);
persistStore(store);
return store
}
这是我的 PrivateRoute
import React from 'react'
import { Route, Redirect } from 'react-router'
import { connect } from 'react-redux'
import * as reducers from '../reducers'
const PrivateRoute = ({ component: Component, isAuthenticated, ...rest }) => (
<Route {...rest} render={props => (
isAuthenticated ? (
<Component {...props}/>
) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}}/>
)
)}/>
);
const mapStateToProps = (state) => ({
isAuthenticated: reducers.isAuthenticated(state)
});
export default connect(mapStateToProps, null)(PrivateRoute);
最后,这是我的主要 App 路由器
function LandingApp() {
return (
<ConnectedRouter history={history}>
<Switch>
<PrivateRoute exact path="/(app|profile)" component={App}/>
<Route exact path="/" component={Theme1}/>
<Route exact path="/login" component={Login1}/>
<Route exact path="/signup" component={SignUp1}/>
<Route exact path="/privacy" component={Privacy}/>
<Route exact path="/tos" component={Terms}/>
<Route component={NotFound}/>
</Switch>
</ConnectedRouter>
)
}
export default LandingApp;
我不得不将我的路由器包裹在 PersistGate
ReactDOM.render(
<Provider store={store}>
<PersistGate persistor={persistStore(store)}>
<LandingApp/>
</PersistGate>
</Provider>, document.getElementById('root'));