我有一個顯示很多產品的目錄頁面,一旦使用者點擊他可能從底部選擇的產品之一,比如說產品編號1000,他就會轉到另一個頁面,檢查內容等...並且當當他使用後退按鈕瀏覽器返回目錄頁面時,所有內容都會再次呈現,這是有道理的,但需要花費大量時間將滾動條定位到先前選擇的產品。
當使用者在頁面頂部選擇某個產品(例如產品編號 4)時,一切都運作良好,但當他轉到底部時,場景就開始了。
有什麼辦法可以在 REACT 中快取這個目錄頁面嗎?為了避免渲染所需的時間?
目錄頁面底部的分頁解決了此問題,但我有一個「加載更多」按鈕。我嘗試使用 React.memo,但它僅在我在當前頁面上執行操作時有效,而不是在我使用後退按鈕登陸頁面時有效。
我正在使用React Router v5。我可以在此處添加一些帶有代碼的代碼筆,但首先我想知道這是否可行,以便採取一些方向。我看到頁面甚至需要在使用後退按鈕返回後渲染所有內容,看起來像靜態頁面,並且滾動甚至不會移動到最後選擇的產品的位置。黑暗中還有光嗎?
這是我的例子。
App.jsx
##import React, { StrictMode } from 'react'; import { BrowserRouter, Switch, Route, Link } from 'react-router-dom' import './App.css'; import Home from './Home'; import Page1 from './Page1'; import Page2 from './Page2'; function App() { return ( <StrictMode> <BrowserRouter> <div className="App"> <header className="App-header"> <Link to='/'>home</Link><br /> <Link to='/page1'>page 1</Link><br /> <Link to='/page2'>page 2</Link><br /> </header> <Switch> <Route path='/page1'> <Page1 /> </Route> <Route path='/page2'> <Page2 /> </Route> <Route path='/'> <Home /> </Route> </Switch> </div> </BrowserRouter> </StrictMode> ); } export default App;
Home.jsx
#import React from 'react'; const Home = () => <h1>This is the home</h1> export default Home;
Page1.jsx
import React, { useEffect, useState } from 'react'; import Card from './Card'; const Page1 = () => { const [cards, setCards] = useState([]); const fetchData = () => { fetch('https://jsonplaceholder.typicode.com/photos') .then((response) => response.json()) .then((json) => setCards(json)) .then(() => scrollToElement()); } const scrollToElement = () => { const id = localStorage.getItem('idRef'); if (id) { var access = document.getElementById(id); access.scrollIntoView(); } } useEffect(() => { fetchData() }, []) return ( <div className="grid"> {cards.map((item) => <Card item={item} key={item.id}/>)} </div> ) } export default Page1;
Page2.jsx
import React from 'react'; const Page2 = () => <h1>Product selected... now click back browser button</h1> export default Page2;
問題
因此,應用程式中存在一些對您不利的因素。
可能的建議解決方案
為了解決狀態持久性問題,這裡的解決方案是將狀態提升到共同祖先的模式,使其比正在渲染的路由元件持續更長時間。在父
App
元件中或自訂 React Context 提供者元件就足夠了。範例:
為了解決需要渲染的資料量問題,您可以轉向虛擬化或視窗化。
react-window
就是處理這個問題的一個。其作用是,它不會將整個資料數組(可能有數千個元素)渲染到 DOM,而是僅渲染適合螢幕的內容以及前後的一些「過度掃描」。範例:
最後要解決的一件事是滾動恢復到特定元素。
react-window
能夠捲動到特定索引。我們可以更新CardDataContext
以保持某些滾動狀態,並更新Page1
元件以設定和恢復位置。演示