重定向时获取用户信息

Fetch user info when redirected

在我的应用程序中,我想在登录后将用户重定向到主页时获取一些用户信息。为此,我使用带有空数组的 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)
    }
  };

我获取令牌的后端代码 header 并验证它以获取用户信息

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

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

由于您已经将此组件包装在 <Router/> 中,因此您可以访问 useLocation(),它可用于在位置更改时触发 fetchUser 函数。

除了以下答案之外,您还可以通过将 forceRefresh 添加到 <Router/> 来强制站点在路由更改时重新加载。例如:<Router forceRefresh ></Router> and a 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演示