Window Addeventlistener Scroll Not Working React

Det är ganska vanligt att vi behöver använda en React ref för att få åtkomst till ett DOM-element på sidan. Till exempel behöver vi använda en React ref för att koppla en scrolllyssnare till en div. Det visar sig att detta inte alltid är så rakt framåt..

Starting simple

Låt oss använda ett mycket enkelt exempel – föreställ dig att vi vill koppla en scroll-lyssnare till en div på sidan.

importera React från ‘react’;

export default function App() {

useEffect(() => {

});

return (

När detta innehåll är högre än föräldern, så scrollar det.

);

}

För att visa en enkel demo har stilen satts upp på följande sätt:

.scrollableContainer {

bredd: 200px;

höjd: 300px;

overflow-y: auto;

}

Detta fungerar bra. När vi scrollar ser vi ‘scrolling’ utskrivet i konsolen. Här är..

Problemlösning: Scroll-händelselyssnare fungerar inte i React

Exemplet blir mer intressant när vi vill visa data från servern och visa en laddningsindikator.

Exemplet nedan är förenklat för att framhäva de mest intressanta delarna. Kärnan är följande:

const [itemsFromServer, setItemsFromServer] = useState(null);

useEffect(() => {

fetchItemsFromServer()

.then((items) => setItemsFromServer(items));

});

I React kan du använda useEffect-hooket för att lägga till en händelselyssnare på ett element. I det här fallet använder vi useRef-hooket för att hämta referensen till ett div-element och sedan lägger vi till en lyssnare för scroll-händelsen med addEventListener-metoden. När scroll-händelsen inträffar kommer handleScroll-funktionen att kallas.

Om itemsFromServer är falskt, returnera en .

return (

)

Kan du hitta problemet? På vilken rad kommer koden att krascha?

const div = ref.current;

div.addEventListener(‘scroll’, handleScroll);

Ovanstående kod skapar en händelselyssnare för scroll-händelsen på en specifik div-element. När användaren rullar innehållet i diven kommer funktionen handleScroll att kallas.

Varför är det så? Det beror på att första gången vår komponent körs returnerar vi och därför renderas inte div-elementet. ref.current sätts korrekt till undefined.

Om en div-element finns, lägger vi till en händelselyssnare för scroll-händelsen genom att använda metoden addEventListener. Vi anger också att funktionen handleScroll ska kallas när scroll-händelsen inträffar.

Nu kraschar inte vår kod längre, men scroll-lyssnaren är heller aldrig kopplad! Varför är det så? Låt oss titta närmare på hur vi använder useEffect.

You might be interested:  Samsung Galaxy S9 och Note 9: En episk strid mellan två teknikgiganter!

När vi fokuserar på beroendena för hooken – arrayen – inser vi att hooken bara körs när funktionen handleScroll ändras. Detta beroende lades automatiskt till av eftersom vi använder handleScroll inuti hooken.

I praktiken vet vi att funktionen handleScroll aldrig ändras när vår komponent renderas om. Det betyder att vår hook bara körs en gång. Vid första renderingen visar vi laddningsindikatorn, så det finns ingen div att fästa scroll-lyssnaren på. När datan från servern har hämtats renderas vår komponent om och vi renderar div-elementet. Men vår hook körs aldrig igen, så den fäster aldrig scroll-lyssnaren…

Fönster addEventListener Scroll fungerar inte i React

Eftersom vi har lagt till itemsFromServer i listan över beroenden kommer hooken nu att köras igen och korrekt fästa scroll-lyssnaren på div-elementet på sidan. Vår kod fungerar nu..

Som vi nyss såg är beroendet av itemsFromServer kritiskt för att vår kod ska fungera. För någon som läser koden senare kommer det dock inte vara uppenbart varför beroendet på itemsFromServer behövs. De måste förstå att itemsFromServer verkligen är hur vi bestämmer om div-elementet, som ref hänvisar till, ska renderas! I en verklig situation där vi har mycket mer kod krävs det ganska mycket ansträngning för att förstå det icke-uppenbara beroendet mellan ref.current och itemsFromServer. Lint-verktyget förstår inte detta implicita beroende på itemsFromServer och därför kommer linter inte klaga om någon tar bort det senare, vilket leder till att vår kod slutar fungera..

Detta blir ännu värre när useEffect är innesluten i en anpassad hook. Till exempel:

Användningen av usePagination-hooken gör det möjligt att hämta objekt från servern och hantera paginering. Vi skickar in en funktion fetchItemsFromServer samt en referens ref som argument till hooken. Om itemsFromServer är falskt, vilket innebär att vi inte har fått några objekt från servern ännu, visas istället en laddningsindikator tills dess att datan har hämtats.

} return (

).

I användningen av usePagination har vi implementerat följande:

Problem med att använda ref.current i React för att lyssna på scrollhändelser i fönstret

Unfortunately, this does not work. The linter gives us a really good explanation:

Detta är en utmärkt linter-fel eftersom det innehåller exakt vad vi behöver veta.

Mutable values like ‘ref.current’ aren’t valid dependencies because mutating them doesn’t re-render the component.

Problemlösning: Scroll-funktionen fungerar inte korrekt i React med window.addeventlistener

För att lösa problemet kan vi se till att div-elementet alltid renderas.

return (

<>

)

div-elementet scrollableContainer renderas alltid. Vår hook behöver bara de beroenden som rekommenderas av linter-verktyget.

You might be interested:  Varför fungerar inte min Ethernet men Wifi gör det?

Om vi använder en anpassad hook som usePagination, kommer det också att fungera.

Användningen av usePagination (fetchItemsFromServer, ref) gör det möjligt att hämta objekt från servern med hjälp av paginering. Detta innebär att endast en delmängd av objekten hämtas åt gången, vilket kan vara användbart om det finns många objekt som behöver visas på en sida. Genom att ange fetchItemsFromServer-funktionen och en referens till elementet där innehållet ska visas kan vi kontrollera när fler objekt ska hämtas baserat på scrollhändelsen hos detta element. På så sätt kan vi dynamiskt lägga till mer innehåll allteftersom användaren rullar ner i sidan utan att överbelasta webbläsaren med onödig data vid första laddning.

Det här är fortfarande känsligt. Om någon senare justerar vår komponent för att rendera div-elementet villkorligt kommer inte scroll-lyssnaren att fästa sig..

Lösning på problemet: Scroll-funktionen fungerar inte med addEventListener i React

Det renaste lösningen jag hittade är att introducera en komponent som hanterar de två logiskt relaterade sakerna: ref och att fästa scroll-lyssnaren.

Funktionen ScrollableList tar emot egenskaper (props) och returnerar dem. Vi använder useRef() för att skapa en referens till ett DOM-element, och useEffect() används för att köra kod när komponenten har renderats. I detta fall är det tomma parentesen i useEffect(), vilket innebär att koden kommer att köras bara en gång vid den initiala renderingen.

Observera att div-elementet renderas oavsett i denna enkla komponent.

export default function App() {

useEffect(() => {

if (!itemsFromServer) return;

return () => {

};

}, [itemsFromServer]);

const handleScroll = () => {

// Kod för att hantera scrollhändelsen

};

return (

);

}

Vi återgår också en funktion i useEffect-funktionen som tar bort händelselyssnaren när komponenten avmonteras eller uppdateras.

Problem med att lyssna på scrollhändelser i React

Den slutgiltiga lösningen är trevlig och mycket enkel. Det tog oss lite tid att komma dit, då vi utforskade olika alternativ och fördjupade oss i React API:er som Refs och Hooks. Förhoppningsvis kommer denna artikel att hjälpa dig när du arbetar med React Refs och funderar över hur du ska strukturera din React-applikation.

Hur rullar man ett fönster i React?

I React kan du använda scrollIntoView() metoden för att scrolla till ett element. Det finns en viktig skillnad mellan de två metoderna. Du behöver anropa scrollIntoView() metoden på själva elementet för att det ska fungera. Med hjälp av denna metod kan du smidigt navigera till önskat element på sidan genom att automatiskt rulla ner eller upp beroende på var det befinner sig i dokumentet. Detta är särskilt användbart när du har långa listor eller innehåll som inte får plats på skärmen samtidigt och vill guida användaren direkt till specifika delar av sidan utan manuell scrolling.

You might be interested:  Epson Scan, Varför Fungerar Du Inte på Windows 10?

Lägg till en händelselyssnare för scrollning

Metod 2: Användning av addEventListener

– Det andra argumentet kommer att vara en callback-funktion för händelsehanteraren. Detta är den funktion som kommer att köras när händelsen inträffar.

– Slutligen används console.log() för att skriva ut informationen.

Följande lista visar stegen för att använda addEventListener-metoden:

1. Välj det element där du vill lyssna på scroll-händelser.

2. Anropa metoden addEventListener() på det valda elementet.

4. Som det andra argumentet, definiera en callback-funktion som ska köras när scroll-händelsen inträffar.

5. Inuti callback-funktionen kan du utföra olika åtgärder baserat på vad du vill uppnå vid scroll-händelsen (t.ex. ändra CSS-stilar eller manipulera DOM).

6. Om du behöver tillgång till specifik information om själva scroll-händelsen kan du använda event-objektets egenskaper och metoder inom callback-funktionen.

7. Slutligen kan du använda console.log() eller liknande metoder för att skriva ut relevant information i webbläsarens konsol.

How do I make my page scrollable React?

För att skapa en scroll i React behöver du först importera React och skapa en React-komponent. I komponentens JSX kan du använda div-elementet med en specificerad höjd och overflow-egenskapen satt till ‘scroll’ för att skapa ett område som går att scrolla.

1. Importera React: Börja med att importera React från react-paketet.

2. Skapa en komponent: Definiera din egen komponent genom att utvidga den inbyggda Component-klassen från react-paketet.

3. Använd JSX: Inuti render-metoden kan du använda JSX-syntaxen för att definiera ditt gränssnitt.

4. Lägg till ett div-element: Placera ett div-element inuti return-satsen i render-metoden.

5. Ange höjden på div-elementet: Sätt höjden på div-elementet genom att ange dess style-attribut, t.ex.: style={{ height: ‘300px’ }}.

6. Aktivera scrollning: Sätt overflow-egenskapen på div-elementets style-attribut till ‘scroll’, t.ex.: style={{ overflowY: ‘scroll’ }}.

7. Fyll med innehåll: Lägg till det önskade innehållet inne i det scrollbara området, antingen direkt eller genom andra element som placeras därinne.

Detta är de grundläggande stegen för att skapa en scrollbar yta i din React-applikation!

Förklaringen bakom varför window scrollY är 0

Om dokumentet inte har blivit rullat uppåt eller nedåt alls, så är scrollY 0. Detta betyder att ingen vertikal skrollning har ägt rum.

1. ScrollY är ett värde som visar hur mycket ett dokument har blivit rullat vertikalt.

2. Om scrollY är 0 betyder det att inget vertikal skrollning har skett.

3. Detta kan inträffa när man först öppnar eller laddar om en webbsida och den inte behöver bli rullad upp eller nedåt för att visa hela innehållet.