我一直在做一个 React 项目,大约 4 天前我遇到了一个问题。当我尝试在新选项卡中打开链接时,它会重定向到 home/BASE url。我需要帮助修复错误。
渲染路由方法
export const renderRoutes = (routes = []) => (
<Suspense fallback={<Loader />}>
<Switch>
{routes.map((route, i) => {
const Guard = route.guard || Fragment;
const Layout = route.layout || Fragment;
const Component = route.component;
return (
<Route
key={i}
path={route.path}
exact={route.exact}
render={(props) => (
<Guard>
<Layout>
{route.routes
? renderRoutes(route.routes)
: <Component {...props} />}
</Layout>
</Guard>
)}
/>
);
})}
</Switch>
</Suspense>
);
GuestGuard
const GuestGuard = (props) => {
console.log(props, BASE_URL)
if (props.isLoggedIn) {
console.log(BASE_URL)
return <Redirect to={BASE_URL} />;
}
return (
<React.Fragment>
{props.children}
</React.Fragment>
);
};
GuestGuard.propTypes = {
isLoggedIn: PropTypes.bool.isRequired
}
const mapStateToProps = (state) => ({
isLoggedIn: state.auth.isLoggedIn
})
export default connect(mapStateToProps, )(GuestGuard);
AuthGuard
const AuthGuard = ({ children, isLoggedIn }) => {
// console.log(children, 393)
if (!isLoggedIn) {
return <Redirect to="/auth/signin-1" />;
}
console.log("LOGGED IN", children.props)
return (
<React.Fragment>
{children}
</React.Fragment>
);
};
AuthGuard.propTypes = {
isLoggedIn: PropTypes.bool.isRequired
}
const mapStateToProps = (state) => ({
isLoggedIn: state.auth.isLoggedIn
})
export default connect(mapStateToProps, )(AuthGuard);
应用(提供者来自 react-redux)
const App = () => {
useEffect(() => {
store.dispatch(init());
}, [])
return (
<Provider store={store}>
<Router basename={BASENAME}>
<React.Fragment>
{renderRoutes(routes)}
</React.Fragment>
</Router>
</Provider>
);
};
export default App;
在useEffect中调用的init方法
export const init = () => (dispatch) => {
try {
const serviceToken = window.localStorage.getItem('serviceToken');
if (serviceToken) {
setSession(serviceToken);
axios.get('http://localhost:8000/api/auth/user', tokenConfig())
.then(response => {
const user = response.data;
dispatch({
type: ACCOUNT_INITIALISE,
payload: {
isLoggedIn: true,
user
}
})
}).catch(err=>{
dispatch({
type:LOGOUT
})
})
} else {
dispatch({
type: ACCOUNT_INITIALISE,
payload: {
isLoggedIn: false,
user: null
}
});
}
} catch (err) {
console.error(err);
dispatch({
type: ACCOUNT_INITIALISE,
payload: {
isLoggedIn: false,
user: null
}
});
}
};
store(与 App.js 在同一个目录下)
import {createStore, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import rootReducer from './reducers/index'
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(...middleware),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
)
);
export default store;
auth reducer
const initialState = {
isLoggedIn: false,
isInitialised: false,
user: null
};
export default function (state = initialState, action) {
switch (action.type) {
case ACCOUNT_INITIALISE: {
const { isLoggedIn, user } = action.payload;
return {
...state,
isLoggedIn,
isInitialised: true,
user
};
}
case LOGIN: {
const { user } = action.payload;
return {
...state,
isLoggedIn: true,
user
};
}
case LOGOUT: {
localStorage.removeItem('serviceToken');
return {
...state,
isLoggedIn: false,
user: null
};
}
default: {
return { ...state };
}
}
}
答案 0 :(得分:1)
我认为您需要在此处调试应用程序流程。下面似乎是根本原因,当链接在新选项卡中打开时,它受 authGuard 保护,并且“useEffect 中调用的 init 方法”正在异步调用 api。因此 authGuard 第一次获取 isloggedIn false 并重定向到“/auth/signin-1”。同时, isloggedIn 设置为 true 并且 guestGuard 重定向到登录页面。
这里有以下选项: 除非您从 api 得到响应,否则不要加载您的路由器。收到响应时显示加载程序。
希望您在这里找到错误,这个答案可以帮助您修复相同的问题。