• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

infinite scroll React.js - intersection observer typescript

Object Storage Arubacloud
0 głosów
279 wizyt
pytanie zadane 14 października 2020 w JavaScript przez poldeeek Mądrala (5,980 p.)

Próbuję napisać infinite scroll w React i typeScript. Komponent jest ogólnie długi więc wkleje tylko najważniejsze rzeczy.

Póki co próbuję osiągnąć stan, w którym konsola wypisywałaby mi cokolwiek, jeśli tylko <ClipLoader /> pojawi się na ekranie użytkownika. Oczywiście ponad nim są rzeczy tylko tutaj je wyciąłem, aby wyrzucić zbędny kod.
Na chwilę obecną typeScript wyrzuca mi taki błąd :
 

Argument of type 'null' is not assignable to parameter of type 'Element'.ts(2345)

w liniach :
 

    if (loader && loader.current) observer.observe(loader.current);

[...]

      if (loader.current) observer.unobserve(loader.current);

Podkreślone są load.current jako argumenty do observer.observe/unobserve...
 

  const loader = useRef(null);

  const loadMore = useCallback((entries) => {
    console.log(entries);
    if (entries[0].isIntersecting) console.log(entries[0].isIntersecting);
  }, []);

  useEffect(() => {
    const options = {
      root: null,
      rootMargin: "0px",
      threshold: 0.1,
    };

    const observer = new IntersectionObserver(loadMore, options);

    if (loader && loader.current) observer.observe(loader.current);

    return () => {
      if (loader.current) observer.unobserve(loader.current);
    };
  });

[...]

return (
[...]

      {!loading && <ClipLoader ref={loader} color={"#276a39"} />}
)

 

1 odpowiedź

+1 głos
odpowiedź 14 października 2020 przez ScriptyChris Mędrzec (190,190 p.)
wybrane 14 października 2020 przez poldeeek
 
Najlepsza

Pokaż proszę co rzuci do konsoli console.log(loader) wstawiony gdzieś na początku callbacka do useEffect.

Komponent ClipLoader jest tworzony w zależności od wartości zmiennej loading, a useEffect odpala callback (z m.in. IntersectionObserverem) przy każdym renderze komponentu (nie ograniczyłeś tego drugim parametrem), w którym się znajduje - możliwe, że to się dzieje zanim komponent ClipLoader będzie utworzony i przypisze referencję do loader. Obstawiam, że stąd bierze się błąd, że property loader.current jest null-em.

Inna rzecz, że React zdaje się nie obsługiwać ref na funkcyjnych komponentach, więc jeśli ClipLoader takim jest, to użyj forwardRef.

komentarz 14 października 2020 przez poldeeek Mądrala (5,980 p.)

Error wygląda następująco:
 

Argument of type 'null' is not assignable to parameter of type 'Element'.  TS2345



Poprawiłem trochę kod.

ClipLoader'a wrzuciłem w takiego diva:
 

      <div ref={loader}>{loading && <ClipLoader color={"#276a39"} />}</div>

i dodałem do tablicy warunków wykonania useEffect loader i loadMore:
 

  useEffect(() => {
    const options = {
      root: null,
      rootMargin: "0px",
      threshold: 0.1,
    };

    const observer = new IntersectionObserver(loadMore, options);

    if (loader && loader.current) observer.observe(loader.current);

    return () => {
      if (loader.current) observer.unobserve(loader.current);
    };
  }, [loader, loadMore]);

 

I jest progres, ponieważ nawet na stronie z errorem jeśli scrolluje w dół i dojadę do końca strony wykonuje się funkcja:
 

  const loadMore = useCallback((entries) => {
    console.log(entries);
    if (entries[0].isIntersecting) console.log(entries[0].isIntersecting);
  }, []);

Jednak sam error, o którym napisałem na początku wciąż się pojawia.

1
komentarz 14 października 2020 przez ScriptyChris Mędrzec (190,190 p.)

Error wygląda następująco:

Pytałem o log z konsoli przeglądarki, ale jak rozumiem apka się nie buduje przez błąd kompilacji TS'a.

Spróbuj tworząc zmienną loader nadać typ HTMLDivElement dla wywołania useRef - tutaj jest przykład: https://linguinecode.com/post/how-to-use-react-useref-with-typescript#useref-examples

Ewentualnie w miejscu, gdzie TS rzuca błąd użyj operatora as -> loader.current as Element - co da znać TS'owi, że ma do czynienia z elementem HTML a nie nullem.

Niewykluczone, że będziesz musiał wspomniane typy zaimportować do komponentu, aby móc ich używać.

1
komentarz 14 października 2020 przez poldeeek Mądrala (5,980 p.)

HTMLDivElement dla loadera załatwiło sprawę. 

komentarz 14 października 2020 przez poldeeek Mądrala (5,980 p.)
Mam jeszcze pytanie odnośnie IntersectionObserver, ponieważ na wersji dekstopwej aplikacji, mam zamiar taki infinity scroll zrobić w kilku miejscach i będą one czasami dostępne jednocześnie. Np. posty na stronie głównej i powiadomienią po otwarciu DropMenu z powiadomieniami, a z tego co się domyślam w funkcji callback IntersectionObserver dostaję tablicę - entries, w której pewnie mam wszystkie divy, które akutalnie obserwuje. One są w jakiś sposób rozpoznawalne ? Bo na wszystkich przykładach jakie obejrzałem ludzie po prostu biorą entries[0] i na niej działają...
1
komentarz 14 października 2020 przez ScriptyChris Mędrzec (190,190 p.)

z tego co się domyślam w funkcji callback IntersectionObserver dostaję tablicę - entries, w której pewnie mam wszystkie divy, które akutalnie obserwuje. One są w jakiś sposób rozpoznawalne ?

Nie do końca. W callbacku, pierwszy parametr - entries - jest tablicą wpisów odnoszących się do obserwowanych elementów, na których API odnotowało zmianę w intersekcji. Każdy wpis w tablicy jest obiektem zawierającym m.in. property target, które jest referencją do elementu w DOM. Jeśli więc Twoje obserwowane elementy mają charakterystyczne atrybuty, typu id lub klasa, to powinno się dać te elementy bez problemu zidentyfikować.

https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#Targeting_an_element_to_be_observed

Podobne pytania

0 głosów
1 odpowiedź 627 wizyt
pytanie zadane 1 czerwca 2018 w JavaScript przez Artek Stary wyjadacz (11,800 p.)
+2 głosów
2 odpowiedzi 361 wizyt
pytanie zadane 8 sierpnia 2021 w Rozwój zawodowy, nauka, praca przez ShockWave Bywalec (2,350 p.)
+2 głosów
0 odpowiedzi 130 wizyt
pytanie zadane 18 kwietnia 2021 w JavaScript przez Puszkin Nowicjusz (170 p.)

92,584 zapytań

141,434 odpowiedzi

319,670 komentarzy

61,967 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...