如何在React JS中的其他组件中单击返回时保持当前页码处于活动状态。我有三个组件,第一个是设计组件,第二个是分页组件,第三个是项目细节组件。当我点击来自API的数据时,它使用ID并将我带到该特定ID的ItemDetails组件。在ItemDetails组件中,我创建了一个“返回”按钮。我想回到我点击ID的当前页面,但当我点击返回按钮时,它会将我带到第一页。
这里是我的设计组件,我想使用localStorage概念,但如何使用它?我不知道。
// /* 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([]);
const [currentPage, setCurrentPage] = useState(1);
useEffect(() => {
const data = window.localStorage.getItem('pnum');
console.log(`data is: ${data}`)
if(data !== null) setCurrentPage(JSON.parse(data))
},[])
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>{item.name}</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>
</>
);
}
我的itemDetails组件是:
import { useParams } from 'react-router-dom';
import { Link } from 'react-router-dom';
const ItemDetails = () => {
const { id } = useParams();
return (
<div>
<h2>Item Details</h2>
<p>{`${id}:I am stuck there.`}</p>
<Link to={`/`} style={{ textDecoration: 'none' }}>Go Back</Link>
</div>
);
};
export default ItemDetails;
2条答案
按热度按时间myzjeezk1#
如果你能提供这个问题的一些最小复制并链接它,可能更容易给予一个有意义的答案,但我们可以尝试一下。
关于如何构建代码来实现这一点,有许多设计决策,这取决于您和您的需求选择什么。现在你的本地存储解决方案是好的,但除非有一些其他的原因,坚持在那里,我个人不会去。如果合适的话,你可以把它保存在树中更高的位置,或者作为url参数,但是我会在后面给予更多的细节。
说实话,我不太确定,没有访问的代码,为什么效果持久的页码不工作。如果我没记错的话,在react中,钩子应该按照声明的顺序运行,我不确定这是一个保证。但即使它是我认为这不是最坚固的设计。
这里有一些替代方案,我不会完全深入,因为有很多可能的变化和大量的文档,所以我只会简要地解释可能的方法,如果你想在一个特定的细节,我可以编辑。
状态您可以将页面保持为状态,只要该状态对于您希望其持久化的所有路由都是通用的。这意味着详细信息页面应该呈现为Design组件的子组件。最极端的例子是将页码存储为应用状态,在此上下文中,react router意味着在树中定义路由或更高路由的组件上。然后它可以与上下文一起暴露,甚至作为 prop 传递,尽管这不是很实用。上下文似乎也不太实际。因此,理想情况下,您应该将其设置为将详细信息页面呈现为Design的后代。有很多方法,它可以是一个对话框/模态,它可以是一些嵌套的路由与出口,为React路由器,你可以查找许多方法。
URL param您也可以将页码设置为可选的url参数,以类似于本地存储的方式更新,然后当您返回时,它将是同一页面,并且您可以更新链接以使用历史记录或类似内容,您甚至可以查看历史记录中的上一个条目并将其显式设置为href。这也具有可以共享页面等的优点。如果有人共享链接,则他们将转到相同的分页,这对于用户来说是方便的。
总而言之,我认为这两种方法都不错,你甚至可以将它们结合起来。我认为如果你研究路由之间的共享状态和url参数,你将在一个很好的位置,你试图实现。
cdmah0mi2#
在将初始值设置为状态时,从本地存储中设置值。