Rumah  >  Soal Jawab  >  teks badan

REACT - elakkan pemaparan semula halaman pada butang selepas pelayar

Saya mempunyai halaman katalog yang menunjukkan banyak produk, sebaik sahaja pengguna mengklik salah satu produk yang dia boleh pilih dari bawah, katakan nombor produk 1000, dia pergi ke halaman lain, menyemak kandungan dll... dan apabila dia menggunakan butang Kembali Apabila penyemak imbas kembali ke halaman katalog, semuanya dipaparkan semula, yang masuk akal, tetapi mengambil banyak masa untuk meletakkan bar skrol ke produk yang dipilih sebelum ini.

Apabila pengguna memilih produk tertentu (cth. produk nombor 4) di bahagian atas halaman, semuanya berfungsi dengan baik, tetapi apabila dia pergi ke bahagian bawah, senario bermula.

Adakah ada cara untuk cache halaman direktori ini dalam REACT? Untuk mengelakkan masa yang diperlukan untuk membuat persembahan?

Penomboran di bahagian bawah halaman jadual kandungan menyelesaikan masalah ini, tetapi saya mempunyai butang "muat lebih". Saya cuba menggunakan React.memo tetapi ia hanya berfungsi apabila saya melakukan tindakan pada halaman semasa, bukan apabila saya mendarat di halaman menggunakan butang belakang.

Saya menggunakan React Router v5. Saya boleh menambah beberapa codepen dengan kod di sini, tetapi pertama-tama saya ingin tahu sama ada ini boleh jadi saya boleh mengambil beberapa arah. Saya telah melihat halaman yang bahkan perlu memaparkan segala-galanya selepas kembali dengan butang belakang, kelihatan seperti halaman statik, dan penatalan tidak berpindah ke tempat produk terakhir dipilih. Adakah cahaya dalam kegelapan?

Ini contoh saya.

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;

Halaman1.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;

Halaman2.jsx

import React from 'react';

const Page2 = () => <h1>Product selected... now click back browser button</h1>

export default Page2;

P粉733166744P粉733166744205 hari yang lalu403

membalas semua(1)saya akan balas

  • P粉762447363

    P粉7624473632024-03-28 10:38:14

    Soalan

    Jadi, terdapat beberapa perkara yang berkesan terhadap anda dalam apl.

    1. Data diambil dan disimpan dalam keadaan setempat komponen yang dilayari. Setelah apl menavigasi ke laluan lain, data hilang dan diperoleh semula semasa pemulangan.
    2. Terdapat banyak data untuk diberikan.

    Mungkin cadangan penyelesaian

    Untuk menyelesaikan masalah kegigihan negeri, penyelesaian di sini adalah untuk mempromosikan negeri kepada nenek moyang yang sama supaya ia bertahan lebih lama daripada komponen dihalakan yang diberikan. Dalam komponen induk App atau komponen pembekal Konteks Reaksi tersuai sudah memadai.

    Contoh:

    import { createContext, useContext, useEffect, useState } from "react";
    
    const CardDataContext = createContext({
      cards: [],
    });
    
    const useCardData = () => useContext(CardDataContext);
    
    const CardDataProvider = ({ children }) => {
      const [cards, setCards] = useState([]);
    
      const fetchData = () => {
        fetch("https://jsonplaceholder.typicode.com/photos")
          .then((response) => response.json())
          .then((json) => setCards(json));
      };
    
      useEffect(() => {
        fetchData();
      }, []);
    
      return (
        
          {children}
        
      );
    };
    export default function App() {
      return (
        
    home
    page 1
    page 2
    // <-- card data provided to all routes
    ); }

    Untuk menyelesaikan masalah jumlah data yang perlu diberikan, anda boleh beralih kepada virtualisasi atau windowing. react-window adalah yang menangani masalah ini. Apa yang dilakukan oleh ini ialah, bukannya memaparkan keseluruhantatasusunan data (berpotensi ribuan elemen) ke DOM, ia hanya memaparkan perkara yang sesuai pada skrin dengan beberapa "pengimbasan berlebihan" sebelum dan selepas.

    Contoh:

    import { FixedSizeList as List } from "react-window";
    import AutoSizer from "react-virtualized-auto-sizer";
    
    const Page1 = () => {
      const { cards } = useCardData();
    
      return (
        
    {({ height, width }) => ( {({ index, style }) => (
    )}
    )}
    ); };

    Satu perkara terakhir yang perlu diperbaiki ialah menatal kembali ke elemen tertentu. react-window 能够滚动到特定索引。我们可以更新 CardDataContext 以保持某些滚动状态,并更新 Page1 Keupayaan untuk menatal ke indeks tertentu. Kami boleh mengemas kini CardDataContext untuk mengekalkan beberapa keadaan tatal dan mengemas kini komponen Page1 untuk menetapkan dan memulihkan kedudukan.

    const CardDataContext = createContext({
      cards: [],
      scrollIndex: null,
      setScrollIndex: () => {}
    });
    
    ...
    
    const CardDataProvider = ({ children }) => {
      ...
      const [scrollIndex, setScrollIndex] = useState(null);
    
      ...
    
      return (
        
          {children}
        
      );
    };
    const Page1 = () => {
      const { cards, scrollIndex, setScrollIndex } = useCardData();
    
      const listRef = useRef();
    
      useEffect(() => {
        if (scrollIndex) {
          setTimeout(() => {
            listRef.current.scrollToItem(scrollIndex, "center");
          });
        }
      }, [scrollIndex]);
    
      return (
        
    {({ height, width }) => ( {({ index, style }) => (
    setScrollIndex(index)}>
    )}
    )}
    ); };

    Demo

    balas
    0
  • Batalbalas