React中点击浏览器返回按钮避免重复调用loadUserPosts的问题求助
解决方案
1. 修复App组件的登录状态校验逻辑
App组件中当前的useEffect依赖了isLogged,会导致每次isLogged更新时重复发起checkuser请求,形成不必要的循环,这也是点击返回时isLogged反复变化的核心原因之一。我们只需要在App挂载时初始化一次登录状态即可:
修改后的App.js代码:
import { useEffect } from 'react' import { Route, Routes } from 'react-router-dom' import './css/style.css' import Sidebar from './pages/Sidebar' import Posts from './pages/Posts' import { AuthUseContext } from './context/AuthContext'; import Axios from 'axios' function App() { const { isLogged, setIsLogged, userData, setUserData } = AuthUseContext(); useEffect(() => { Axios.post('/checkuser', { userStatus: isLogged, userData: userData }).then((response) => { setIsLogged(response.data.status); setUserData(response.data.userdata); }).catch(function (error) { console.log("Something went wrong.. We are investigating."); }); }, []) // 改为空数组,仅在组件挂载时执行一次 return ( <> <Sidebar /> <div className="content"> <Routes> <Route path="/" element={<Posts />} /> <Route path="*" element={ <h1>Not found (404)</h1> } /> </Routes> </div> </> ); } export default App;
2. 优化Posts组件的帖子加载逻辑
添加一个状态标记帖子是否已加载,避免isLogged变化时重复调用loadUserPosts,同时修复map渲染的语法问题:
修改后的Posts.js代码:
import { useState, useEffect } from "react"; import { AuthUseContext } from '../context/AuthContext'; import Axios from 'axios'; function Posts() { const [posts, setPosts] = useState([]); const [hasLoadedPosts, setHasLoadedPosts] = useState(false); // 新增加载标记状态 const { isLogged, userData } = AuthUseContext(); useEffect(() => { if (isLogged && !hasLoadedPosts && userData.id) { // 仅当用户已登录、未加载过帖子、且userData存在有效id时发起请求 loadUserPosts(); } else if (!isLogged) { // 用户登出时重置状态,保证下次登录能重新加载帖子 setPosts([]); setHasLoadedPosts(false); } }, [isLogged, hasLoadedPosts, userData.id]); // 添加所有必要依赖项 function loadUserPosts() { Axios.post('/posts/load', { user: userData.id }).then((response) => { if(response.data.status === "success") { setPosts(response.data.posts); setHasLoadedPosts(true); // 请求成功后标记为已加载 } }).catch((error) => { console.log("Something went wrong.. We are investigating."); }) } return ( <> {posts.map((p) => ( // 改为括号语法,自动返回渲染元素 <div className="post" key={p.id}> <div className="post-user"> {p.username} </div> <div className="post-text"> {p.message} </div> </div> ))} </> ) } export default Posts
补充说明
- App组件的
useEffect改为空数组后,只会在应用启动时校验一次登录状态,彻底避免了重复请求和isLogged的不必要更新。 - Posts组件通过
hasLoadedPosts标记,确保只有在首次满足登录条件时才加载帖子,点击返回时即使组件重新渲染,只要isLogged状态未变化(或已加载过帖子),就不会重复调用loadUserPosts。 - 添加
userData.id到依赖项中,避免因闭包问题导致请求时使用旧的userData值。
内容的提问来源于stack exchange,提问作者Galbert
相关产品推荐
相关产品推荐

