【问题标题】:React Router redirects to BASE_URL when I try to load a page in a new tab当我尝试在新选项卡中加载页面时,React Router 重定向到 BASE_URL
【发布时间】:2021-04-04 06:31:47
【问题描述】:

我一直在做一个 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
        }
      });
    }
  };

存储(在与 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;

身份验证器

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 };
    }
}
  }

【问题讨论】:

    标签: reactjs django react-redux react-router django-react


    【解决方案1】:

    我认为您需要在此处调试应用程序流程。下面似乎是根本原因,当链接在新选项卡中打开时,它受 authGuard 保护,并且“在 useEffect 中调用的 init 方法”正在异步调用 api。所以 authGuard 第一次得到 isloggedIn false 并重定向到“/auth/signin-1”。同时,isloggedIn 设置为 true,guestGuard 重定向到登录页面。

    您有以下选项: 除非您从 api 获得响应,否则不要加载您的路由器。在收到响应时显示加载程序。

    希望您在这里找到错误,这个答案可以帮助您修复相同的问题。

    【讨论】:

    • 感谢回复@Aman 你建议我如何安排流程?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-04
    • 2021-06-29
    • 2022-12-11
    • 2023-03-10
    • 2018-03-03
    • 2020-07-26
    • 2021-10-19
    相关资源
    最近更新 更多