重定向时获取用户信息

Posted

技术标签:

【中文标题】重定向时获取用户信息【英文标题】:Fetch user info when redirected 【发布时间】:2022-01-16 14:40:47 【问题描述】:

在我的应用程序中,当我在登录后将用户重定向到主页时,我想获取一些用户信息。为此,我使用带有空数组的 useEffect 作为依赖项,因此我仅在组件首次加载时才获取数据。但是,出于某种原因,我只在重新加载主页时才获得数据,而不是在我被重定向时。

登录功能

export const login = ( email, password, history ) => 
  return async (dispatch) => 
    try 
      const response = await fetch("http://localhost:5000/api/login", 
        method: "POST",
        headers: 
          "Content-Type": "application/json",
        ,
        body: JSON.stringify(
          email,
          password,
        ),
      );

      const data = await response.json();
      if (data.status === 200) 
        dispatch(setUser(
          fullname: data.fullname,
          email: data.email
        ));
        localStorage.setItem("userToken", data.user);
        history.push("/");
       else 
        dispatch(
          setNotification(
            variant: "error",
            message: data.message,
          )
        );
      
     catch (e) 
      console.log(e.message);
    
  ;
;

这是我在前端用来获取用户信息的代码

export const fetchUser = () => 
  return async (dispatch) => 
    try 
      const response = await fetch("http://localhost:5000/userInfo", 
        headers: 
          "x-access-token": localStorage.getItem('userToken'),
        ,
      );

      const data = await response.json();
      dispatch(
        setUser(
          id: data.id,
          fullname: data.fullname,
          email: data.email,
        )
      );
     catch (error) 
      console.log(error)
    
  ;

我将令牌作为标头并验证它以获取用户信息的后端代码

module.exports.getCurrentUser = async (req, res) => 
  const token = req.headers["x-access-token"];
  try 
    const verifyToken = jwt.verify(token, "123");
    const user = await User.findOne( email: verifyToken.email );
    return res.json(
      id: user._id,
      fullname: user.fullname,
      email: user.email
    )
  
   catch (error) 
    console.log(error)
  
;

我在 app.js 中调用 useEffect

export default function App() 
  const isAuth = isLoggedIn();
  const dispatch = useDispatch();
  const cart = useSelector((state) => state.cart);

  useEffect(() => 
      dispatch(fetchUser());
  , []);

  useEffect(() => 
    if (!isAuth) 
      return;
    
    if (isInitial) 
      isInitial = false;
      return;
    
      if (cart.changed) 
        dispatch(sendCartData(cart));
      
  , [cart]);

  return (
    <React.Fragment>
      <Switch>
        <Route path="/" exact>
          <Home />
        </Route>
        <Route path="/componentes" exact>
          <Components />
        </Route>
        <Route path="/login" exact>
          <Login />
        </Route>
        <Route path="/cadastro" exact>
          <Register />
        </Route>
        <Route path="/produto/:nomeProduto" exact>
          <SingleProduct />
        </Route>
        <Route path="/componente/suspensao" exact>
          <Suspension />
        </Route>
        <Route path="/componente/quadro" exact>
          <Frame />
        </Route>
        <Route path="/marca/:brand" exact>
          <Brands />
        </Route>
        <Route path="/carrinho" exact>
          <Cart />
        </Route>
        <Route path="/equipamentos" exact>
          <Equipments />
        </Route>
        <Route path="/acessorios" exact>
          <Accessories />
        </Route>
        <Route path="/casual" exact>
          <Casual />
        </Route>
      </Switch>
    </React.Fragment>
  );

【问题讨论】:

您是否有一个 &lt;Router/&gt; 组件将 &lt;Switch/&gt; 包装在比显示的更高级别的组件中?这个重定向是只发生在同一个 react 应用实例中还是一个全新的页面加载? 我有一个包装应用组件的 组件。只发生在同一个 React 应用实例中是什么意思? 只是意味着您只是更改为新的&lt;Route/&gt; 还是涉及完整的页面重新加载。没有更多调试细节很难排除故障 我只是换了一条新路线 那么第二个请求是否会发送到开发工具网络中的userInfo 路径,如果是,它是 200 状态吗?不知道什么是,什么还没有在这里工作 【参考方案1】:

您的&lt;App/&gt; 组件在路由更改时不会被挂载,因为它是&lt;Switch/&gt; 的父组件。因此useEffect(() =&gt; , []); 不会被触发,除非页面被重新加载并且&lt;App/&gt; 由于重新加载而挂载。

由于您已经将此组件包装在 &lt;Router/&gt; 中,因此您可以访问 useLocation(),只要位置发生更改,您就可以使用它来触发 fetchUser 函数。

除了以下答案之外,您还可以通过将forceRefresh 添加到您的&lt;Router/&gt; 来强制您的站点在路由更改时重新加载。例如:&lt;Router forceRefresh &gt;&lt;/Router&gt;。 Here is another answer relating to forceRefresh 和 documentation link。

在您的情况下,将以下内容添加到 useEffect 和导入应该就足够了:


import  useLocation  from 'react-router-dom';

export default function App() 
  const isAuth = isLoggedIn();
  const dispatch = useDispatch();
  // Use the current browser location from router
  const location = useLocation();
  const cart = useSelector((state) => state.cart);

  // Execute your `fetchUser` whenever the route changes
  useEffect(() => 
      dispatch(fetchUser());
  , [location]);

  useEffect(() => 
    if (!isAuth) 
      return;
    
    if (isInitial) 
      isInitial = false;
      return;
    
      if (cart.changed) 
        dispatch(sendCartData(cart));
      
  , [cart]);

  return (...);

这是一个 CodeSandbox 演示

【讨论】:

以上是关于重定向时获取用户信息的主要内容,如果未能解决你的问题,请参考以下文章

Flask 学习-11.redirect() 重定向

关于在app store上处理iAP成功的问题

在 beforeEnter 路由中访问 VuexStore

如何获取用户 Seller ID、Marketplace ID 和 MWS token?

如何在不重新加载页面的情况下将用户重定向到 redux saga 上的另一个页面

Webview 重定向问题