重定向时获取用户信息
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演示
在我的应用程序中,我想在登录后将用户重定向到主页时获取一些用户信息。为此,我使用带有空数组的 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
中调用 useEffectexport 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>
。
在您的情况下,将以下内容添加到 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 (...);
}