Иногда, когда вы переключаетесь со списка новостей на страницу сведений о новостях, а затем возвращаетесь, вы теряете состояние и позицию прокрутки. Чтобы избежать этого, вы можете передавать значения с помощью react-router-dom при перемещении между страницами.
поэтому, когда вы перемещаетесь по страницам с подробностями, укажите состояние и положение прокрутки следующим образом.
navigate('/userDetails',{state: {userLists: data,scrollPosition,userInfo: info}})
Захватите событие прокрутки в элементе <div>
и обновите значение следующим образом:
function handleScroll(event) { setScrollPosition(event.target.scrollTop) } <div style={{overflowY: "scroll",height: '100vh'}} ref={scrollRef} onScroll={handleScroll}>
Когда пользователь вернется, верните состояние на страницу новостей:
navigate('/news',{state: location.state})
А в компоненте новостей получите доступ и обновите данные, как показано ниже.
useEffect(()=> { if(location.state){ const {userLists,scrollPosition} = location.state; setData(userLists) scrollRef.current.style.backgroundColor = 'red' setTimeout(() => { scrollRef.current.scrollTop = scrollPosition }, (10)); }else{ getDataFromApi(); } },[])
Помните, что код внутри setTimeout
будет выполняться после небольшой задержки, позволяя DOM установиться перед настройкой положения прокрутки.
А вот пример того, как вы можете применить эту функцию.
import './App.css'; import { useEffect, useRef, useState } from 'react'; import axios from 'axios'; import { BrowserRouter, Route, Routes, useLocation, useNavigate } from 'react-router-dom'; function App() { return ( <BrowserRouter> <Routes> <Route path="/news" element={<UserLists />}/> <Route path="/userDetails" element={<UserDetails />}/> </Routes> </BrowserRouter> ); } const UserLists = () => { const [data,setData] = useState([]); const [scrollPosition,setScrollPosition] = useState(); const navigate = useNavigate(); const location = useLocation(); const scrollRef = useRef(); useEffect(()=> { if(location.state){ const {userLists,scrollPosition} = location.state; setData(userLists) scrollRef.current.style.backgroundColor = 'red' setTimeout(() => { scrollRef.current.scrollTop = scrollPosition }, (10)); }else{ getDataFromApi(); } },[]) const getDataFromApi = async () => { try{ const res = await axios.get('https://reqres.in/api/users'); setData(res.data.data); }catch(err){ console.log("error",err) } } const handleScroll = (event) => { setScrollPosition(event.target.scrollTop) } return ( <div className="App"> <div style={{overflowY: "scroll",height: '100vh'}} ref={scrollRef} onScroll={handleScroll}> {data.map((info) => { return ( <div style={{backgroundColor: "orange"}} onClick={() => { navigate('/userDetails',{state: {userLists: data,scrollPosition,userInfo: info}}) }} > <h2>{info.email}</h2> <h2>{info.first_name}</h2> <h2>{info.last_name}</h2> <img src={info.avatar} /> </div> ) })} </div> </div> ) } const UserDetails = () => { const [userInfo,setUserInfo] = useState(); const navigate = useNavigate(); const location = useLocation(); useEffect(()=> { if(location.state){ const {userInfo} = location.state; setUserInfo(userInfo) } }) return ( <div> <button onClick={() => { navigate('/news',{state: location.state}) }} > Go back to user lists </button> <div style={{ backgroundColor: "skyblue" }} > <h2>{userInfo?.email}</h2> <h2>{userInfo?.first_name}</h2> <h2>{userInfo?.last_name}</h2> <img src={userInfo?.avatar} /> </div> </div> ) } export default App;
И это все…
вы можете задать мне в разделе ответов, если у вас есть какие-либо вопросы