You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React路由返回时如何保持列表状态避免重新加载?

当前行为不符合预期

从详情页点击返回按钮回到列表页时,UsersList组件会被重新挂载,导致组件内的useEffect(空依赖数组)再次执行,重新发起用户列表请求,这和你想要的“返回后不重新加载”需求不符。

你遗漏的核心点

没有将用户列表的状态提升到路由组件的父级(比如App组件),而是把状态和请求逻辑放在UsersList内部。由于React Router在路由切换时会卸载离开的组件、挂载进入的组件,所以每次回到列表页都会重新初始化UsersList的状态并触发请求。

解决方案:状态提升

把用户列表的状态和数据请求逻辑移到App组件中,通过props传递给UsersList。这样App组件不会随路由切换卸载,状态会持久保留,返回列表页时直接使用已加载好的数据。

修改后的代码示例:

App.js

import { useState, useEffect } from 'react'
import {
  BrowserRouter as Router,
  Routes,
  Route,
  Link,
  useParams
} from 'react-router-dom'

function UsersList ({ users }) {
  return (
    <ul>
      {users.map(user => (
        <li key={user.id}>
          <Link to={`/users/${user.id}`}>{user.name}</Link>
        </li>
      ))}
    </ul>
  )
}

function UserDetail () {
  const { id } = useParams() // 用useParams更优雅地获取路径参数
  const [user, setUser] = useState(null)

  useEffect(() => {
    fetch(`https://jsonplaceholder.typicode.com/users/${id}`)
      .then(response => response.json())
      .then(data => setUser(data))
  }, [id])

  if (!user) {
    return <div>Loading...</div>
  }

  return (
    <div>
      <h1>{user.name}</h1>
      <p>{user.email}</p> {/* 原接口无description字段,改用email展示 */}
    </div>
  )
}

function App () {
  const [users, setUsers] = useState([])

  // 仅在App初始化时请求一次数据
  useEffect(() => {
    fetch('https://jsonplaceholder.typicode.com/users')
      .then(response => response.json())
      .then(data => setUsers(data))      
  }, [])

  return (
    <Router>
      <Routes>
        <Route path='/users' element={<UsersList users={users} />} />
        <Route path='/users/:id' element={<UserDetail />} />
      </Routes>
    </Router>
  )
}

export default App

额外优化点

  • 用useParams()替代路径字符串分割,逻辑更简洁且不易出错;
  • 修正了原代码中渲染不存在的description字段问题,改用接口返回的email字段展示。

内容的提问来源于stack exchange,提问作者luisNET

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 03:07:41