所以我有 2 页:1. 客户列表,2. 客户详细信息。因此,客户列表页面将是一个表格,其中包含没有详细信息的客户 ID 列表,但有一个按钮可以导航到另一个客户详细信息页面。代码看起来像这样
const CustomerList = () => {
const [customers, setCustomers] = useState([]);
useEffect(() => { fetch customer list here }, [])
return (
{
customers.map(c =>
<tr>
<td>{customer.customer_id}</td>
<td><button onClick={() => navigate(`/customer/${customer.customer_id}`)}>View details</button></td>
</tr>
)
}
);
}
在客户详细信息页面中还有一个按钮,可以导航回上一页,客户列表,代码如下所示。
const CustomerDetails = () => {
const navigate = useNavigate();
return (
<>
<h2>Customer Details</h2>
<button onClick={() => navigate(-1)}>Back</button>
</>
);
}
但是,当我导航回第一页时,它将完全重新渲染并再次获取整个数据。有没有办法缓存或防止首页重新渲染或重新加载数据,因为加载客户列表需要很长时间,所以我担心这里的用户体验。我正在使用react-router-dom v6,路径结构如下所示。
/ -> root customer-list
/customer/:customerId -> customer-details
按照您实现
CustomerList
组件的方式,每当安装时它都会尝试获取 API,因为状态仅适用于该组件。为了防止这种情况发生,您没有什么选择
将
customers
状态移至其父级,并通过 props 将其传递给 CustomerList
组件。请记住,如果该父级也是在路线更改时被卸载和重新安装的,那么这种情况仍然会发生。因此,您必须再次提升状态,直到始终呈现父级。您可以根据是否将这些数据保留在这样的父级中来决定这一点
使用全局状态解决方案。这样,数据将与您的组件分开,以便您来回导航时不会丢失数据。 Redux 就是其中之一。还有很多。
使用一些数据获取库,如 SWR 或 TanstackQuery。他们有内置的机制来保存缓存
您可以使用 https://reactrouter.com/en/main/components/outlet 来实现此行为。我提供的链接中有一个很棒的示例
来自链接
function Dashboard() {
return (
<div>
<h1>Dashboard</h1>
{/* This element will render either <DashboardMessages> when the URL is
"/messages", <DashboardTasks> at "/tasks", or null if it is "/"
*/}
<Outlet />
</div>
);
}
function App() {
return (
<Routes>
<Route path="/" element={<Dashboard />}>
<Route
path="messages"
element={<DashboardMessages />}
/>
<Route path="tasks" element={<DashboardTasks />} />
</Route>
</Routes>
);
}
或者,如果不想更改当前的路由设置并且不使用全局状态管理器,您可以使用
localStorage
、sessionStorage
或任何适合您用例的浏览器存储 API,这将保留您的数据,而您不需要不需要重新获取它。
https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API