React中点击返回按钮时保留当前页码的实现咨询
解决返回详情页后回到原列表页码的问题
问题分析
当前点击详情页的"Go Back"按钮回到列表页时,会默认回到第一页。我们可以通过localStorage保存用户点击进入详情页时的当前页码,在列表页重新加载时恢复该页码,实现返回原页面的效果。
修改方案
1. 优化Design组件的页码存储与初始化逻辑
将当前页码的初始化逻辑直接放在useState的初始值中,避免异步更新导致的初始显示第一页问题,同时保留页码变化时自动存储的逻辑:
// /* eslint-disable react/prop-types */ // TODO: upgrade to latest eslint tooling import "../src/App.css"; import axios from "axios"; import { useEffect, useState, useMemo } from "react"; import Pagination from "./Pagination"; import { Link } from "react-router-dom"; let PageSize = 2; export default function Design() { const [search, setSearchTerm] = useState("all"); const [records, setRecords] = useState([]); const [suggestions, setSuggestions] = useState([]); // 直接从localStorage读取初始页码,没有则设为1 const [currentPage, setCurrentPage] = useState(() => { const savedPage = window.localStorage.getItem('pnum'); return savedPage ? JSON.parse(savedPage) : 1; }); // 页码变化时自动保存到localStorage useEffect(() => { window.localStorage.setItem('pnum', JSON.stringify(currentPage)); }, [currentPage]) const currentTableData = useMemo(() => { const firstPageIndex = (currentPage - 1) * PageSize; const lastPageIndex = firstPageIndex + PageSize; return records.slice(firstPageIndex, lastPageIndex); }, [currentPage, records]); useEffect(() => { searchRecords(); }, []); const searchRecords = async () => { try { const res = await axios.get(`https://fruityvice.com/api/fruit/${search}`); setRecords(search === "all" ? res.data : [res.data]); } catch (error) { console.error("Error searching record:", error); setRecords([]); } }; const fetchSuggestions = async (input) => { try { const res = await axios.get(`https://fruityvice.com/api/fruit/all`); const fruits = res.data.map((fruit) => fruit.name); const filteredSuggestions = fruits.filter((fruit) => fruit.toLowerCase().includes(input.toLowerCase()) ); setSuggestions(filteredSuggestions); } catch (error) { console.error("Error fetching suggestions:", error); setSuggestions([]); } }; const handleInputChange = (e) => { const inputValue = e.target.value; setSearchTerm(inputValue); fetchSuggestions(inputValue); }; const getTotalNutritions = (item) => { return Object.values(item.nutritions).reduce( (total, value) => total + Math.trunc(value), 0 ); }; return ( <> <h1 className="main--heading">Fruit Project</h1> <div className="main"> <input className="input" onChange={handleInputChange} list="suggestions" placeholder="Search Fruit" /> <datalist id="suggestions"> {suggestions.map((fruit, index) => ( <option key={index} value={fruit} /> ))} </datalist> <button className="btn" onClick={searchRecords}> Search Fruit </button> </div> <div> <table> <thead> <tr> <th>Sr No</th> <th>Name</th> <th>Family</th> <th>Order</th> <th>Nutritions</th> <th>Genus</th> </tr> </thead> <tbody> {Array.isArray(currentTableData) && currentTableData.length > 0 ? ( currentTableData .sort((a, b) => a.id - b.id) .map((item) => ( <tr key={item.id}> <td>{item.id}</td> <td> <Link to={`/details/${item.id}`}>View Details</Link> </td> <td>{item.family}</td> <td>{item.order}</td> <td>{getTotalNutritions(item)}</td> <td>{item.genus}</td> </tr> )) ) : ( <tr> <td>No data available</td> </tr> )} </tbody> </table> <Pagination className="pagination-bar" currentPage={currentPage} totalCount={records.length} pageSize={PageSize} onPageChange={(page) => setCurrentPage(page)} /> </div> </> ); }
2. 可选优化ItemDetails组件的返回逻辑
如果希望更符合浏览器的返回行为,可以将Link替换为useNavigate实现返回上一页,这样即使用户从其他页面进入详情页,也能回到正确的上一级页面:
import { useParams, useNavigate } from 'react-router-dom'; const ItemDetails = () => { const { id } = useParams(); const navigate = useNavigate(); return ( <div> <h2>Item Details</h2> <p>{`${id}:I am stuck there.`}</p> <button onClick={() => navigate(-1)} style={{ textDecoration: 'none', background: 'none', border: 'none', color: 'blue', cursor: 'pointer' }}> Go Back </button> </div> ); }; export default ItemDetails;
原理说明
- 当用户切换列表页码时,
currentPage状态变化,触发useEffect将页码存入localStorage。 - 列表页初始化时,直接从
localStorage读取之前保存的页码作为初始值,确保返回时显示用户之前停留的页面。 - 可选的
navigate(-1)方式利用浏览器历史记录返回,无需依赖localStorage也能回到原页面状态,适合更复杂的路由场景。
内容的提问来源于stack exchange,提问作者Muhammad Sibtain
相关产品推荐
相关产品推荐

