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

React - Komponent bez renderu

Object Storage Arubacloud
0 głosów
134 wizyt
pytanie zadane 20 sierpnia 2021 w JavaScript przez nielotweb Bywalec (2,240 p.)

Cześć, aktualnie uczę się Reacta i mam pewien problem ze zrozumieniem pewnej rzeczy. A dokładnie: Postanowiłem zrobić sobie skrypt który będzie chwytał wszystkie linki na stronie z klasą "hover-this" i potem po najechaniu na jeden z nich zaczął się lekko przesuwać ( przez transform: translate ) - ale to nie problem w samym skrypcie. Problem jest jak to "zamontować" w reactie. W czystym JS zrobiłem sobie <script></script> wrzuciłem cały kod w te tagi i śmigało - a jak to zrobić w reactie?

Na początku zrobiłem normalny komponent funkcyjny w którym dodałem cały kod, a w środku rendera (return) nic nie dałem puste miejsce (<> </>) - i wrzuciłem do głównego pliku App.js gdzie ładowane są wszystkie komponenty ale tam nawet nie łapie linków. Nie mogę sobie tego w głowie ułożyć na jakiej zasadzie mają działać takie odrębne skrypty które nic nie zwracają a coś robią w tle. Ktoś coś? Z góry dziękuję!

A tutaj kod tego skryptu w tym komponencie: 

const LinksHover = (props) => {

    const links = document.querySelectorAll(".hover-this");

    const animateIt = function (e) {
        const a = this.querySelector("span");
        const { offsetX: x, offsetY: y } = e,
        { offsetWidth: width, offsetHeight: height } = this,

        move = 25,
        xMove = x / width * (move * 2) - move,
        yMove = y / height * (move * 2) - move;

        a.style.transform = `translate(${xMove}px, ${yMove}px)`;

        if (e.type === "mouseleave") a.style.transform = '';
    }

    links.forEach(b => b.addEventListener('mousemove', animateIt));
    links.forEach(b => b.addEventListener('mouseleave', animateIt));

    return(
        <>
        </>
    )
}

export default LinksHover;

 

komentarz 20 sierpnia 2021 przez ScriptyChris Mędrzec (190,190 p.)

Gdzie tworzone są te linki i jak używasz komponentu LinksHover?

komentarz 20 sierpnia 2021 przez nielotweb Bywalec (2,240 p.)

Linki są w różnych komponentach na całej stronie (np. menu) - A komponent LinksHover używałem importując do głównego pliku App.js w metode return() - ale w ten sposób nie wyłapywało linków. 

Ale już ktoś poniżej dał dobrą odpowiedź, żeby to wrzucić w useEffect w App.js zamiast odrębny komponent robić do tego - i to działa - tylko pytanie czy to dobry sposób czy można to lepiej zrobić, lub powinno inaczej się takie rzeczy robić?

1
komentarz 20 sierpnia 2021 przez ScriptyChris Mędrzec (190,190 p.)

Twoje podejście jest dość nisko poziomowe i praktycznie pomija kontekst Reacta, bo pobierasz linki bezpośrednio z DOM, a eventy na linkach obsługujesz również przez DOM-ową metodę.

Wg mnie lepiej tutaj skorzystać z kompozycji, otaczając każdą listę z linkami komponentem, który będzie obsługiwał eventy na tych linkach, albo przekazywać do tego komponentu dane, na podstawie których on wyświetli listę linków z obsługą eventów.

Przykłady:

const list = [
  {
    id: 1,
    text: 'qwe'
  },
  {
    id: 2,
    text: 'asd'
  },
  {
    id: 3,
    text: 'zxc'
  },
];

const list2 = [
  {
    id: 7,
    text: 'iop'
  },
  {
    id: 8,
    text: 'jkl'
  },
  {
    id: 9,
    text: 'bnm'
  },
];

function App {
  return <>
    <ListWrapper listData={list}/>

    <ListDecorator>
      {() => {
        return list2.map(listItem => (
          <ul key={listItem.id}>
            <li>{listItem.text}</li>
          </ul>
        ))
      }}
    </ListDecorator>
  </>
}

function ListWrapper({ listData }) {
  const onMouseOver = (event) => console.log('mouseover wrapper event:', event);

  return listData.map(listItem => (
    <ul key={listItem.id}>
      <li onMouseOver={onMouseOver}>{listItem.text}</li>
    </ul>
  ))
    
}

function ListDecorator({ children }) {
  const onMouseOver = (event) => console.log('mouseover decorator event:', event);

  return <div onMouseOver={onMouseOver}>
    {children()}
  </div>
}

Pierwsze podejście to zwyczajne przekazanie danych przez propsy i oddelegowanie do komponentu renderowania, łącznie z podpięciem event handlera na każdy element listy. Drugie podejście korzysta z funkcji children i jedynie podpina event handler na dekorator gotowej listy dostarczonej z góry, korzystając z mechanizmu event delegation - trzeba wtedy samemu zaimplementować filtrowanie odpowiednich elementów, żeby nie brać pod uwagę tych, które nie są elementami listy.

W drugim przypadku można by też skorzystać z ref'a przekazanego jako parametr do funkcji children (i wtedy podpiąć go wewnątrz bezpośrednio na listę), aby nie tworzyć dodatkowego <div>a wokół listy zwróconej przez tą funkcję.

1 odpowiedź

+2 głosów
odpowiedź 20 sierpnia 2021 przez wizarddos Nałogowiec (25,930 p.)
Spróbuj wrzucić ten kod do useEffect() w komponencie App.
1
komentarz 20 sierpnia 2021 przez nielotweb Bywalec (2,240 p.)
A faktycznie, to było takie proste - totalnie zapomniałem, że useEffect jest od takich rzeczy..

Działa więc dzięki wielkie!

Podobne pytania

+1 głos
2 odpowiedzi 430 wizyt
pytanie zadane 29 maja 2021 w JavaScript przez ShockWave Bywalec (2,350 p.)
0 głosów
2 odpowiedzi 2,198 wizyt
pytanie zadane 2 maja 2020 w JavaScript przez kalczur Gaduła (4,320 p.)
0 głosów
1 odpowiedź 450 wizyt
pytanie zadane 25 marca 2021 w Inne języki przez karolina_web Nowicjusz (140 p.)

92,572 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,959 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!

...