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

react, AOS - zmiana state'u gdy element się pokazuje na ekranie.

Object Storage Arubacloud
0 głosów
198 wizyt
pytanie zadane 28 stycznia 2021 w JavaScript przez hakiros54 Obywatel (1,160 p.)

Witam, robię teraz progress bar na stronie, działa on przy pomocy SVG. 

const Progress_bar = () => {
	const stroke = 4;
	const radius = 100;
	const normalizedRadius = radius - stroke * 2;
	const circumference = normalizedRadius * 2 * Math.PI;
	const progress = 75;
	const [strokeDashoffset, setStrokeDashoffset] = useState(circumference);
	useEffect(() => {
		document.addEventListener('aos:in', () => {
			setStrokeDashoffset(circumference - 75 / 100 * circumference);
		});
		document.addEventListener('aos:out', () => {
			setStrokeDashoffset(circumference);
		});
	}, []);
	return (
		<div data-aos="fade-up">
			<svg
				class="progress-ring"
				height={radius * 2}
				width={radius * 2}
			>
				<circle
					class="circle"
					stroke="red"
					stroke-width={stroke}
					strokeDasharray={`${circumference} ${circumference}`}
					style={{ strokeDashoffset }}
					stroke-width={stroke}
					fill="transparent"
					r={normalizedRadius}
					cx={radius}
					cy={radius}
				/>
			</svg>
		</div>
	)
}

ma to działać tak, że gdy zjeżdżam i jestem na odpowiednim poziomie to pojawia mi się ten komponent (dzięki AOS) i wtedy powinienem zmienić wartość strokeDashoffset za pomocą setStrokeDashoffset i pasek zacznie się zapełniać... problem w tym, że nie wiem jak to zrobić by zmienić state w momencie pojawienia się elementu. W dokumentacji (https://github.com/michalsnik/aos) znalazłem coś takiego:

AOS dispatches two events on document: aos:in and aos:out whenever any element animates in or out, so that you can do extra stuff in JS:

document.addEventListener('aos:in', ({ detail }) => {
  console.log('animated in', detail);
});

document.addEventListener('aos:out', ({ detail }) => {
  console.log('animated out', detail);
});

problem w tym, że nie wiem jak mogę tego użyć do zmiany state'a.

komentarz 28 stycznia 2021 przez ScriptyChris Mędrzec (190,190 p.)

Czy event listenery, które podpiąłeś są w ogóle wołane? Czy wartości przekazywane do funkcji setStrokeDashoffset w listenerach są prawidłowymi dla bindingu style na komponencie <circle />? Czy w konsoli są jakieś błędy?

komentarz 28 stycznia 2021 przez hakiros54 Obywatel (1,160 p.)
listener się nie odpala (a próbowałem go wsadzić i do <App /> i do Progress_bar. Nie wyświetla nic w konsoli. A wartości są dobre, jak je przekazywałem ręcznie to wypełniało się do określonego miejsca. Problem polega też na tym, że nawet jakby się to odpalało to nie wiadomo dla którego komponentu miałoby się odpalać, w końcu takich progress barów będzie kilka, każdy będzie miał swój setStrokeDashoffset każdy z innymi wartościami
komentarz 28 stycznia 2021 przez ScriptyChris Mędrzec (190,190 p.)
edycja 28 stycznia 2021 przez ScriptyChris

listener się nie odpala 

A czy sam callback przekazany do useEffect się uruchamia (wstaw tam console.log i zobacz czy konsola go pokaże)?

A wartości są dobre, jak je przekazywałem ręcznie to wypełniało się do określonego miejsca

Czyli ogólnie ten AOS działa i nie pominąłeś konfiguracji wspomnianej w dokumentacji? Animacje też działają? Można je w razie czego konfigurować (choć powinny mieć jakieś defaultowe ustawienia).

Problem polega też na tym, że nawet jakby się to odpalało to nie wiadomo dla którego komponentu miałoby się odpalać, w końcu takich progress barów będzie kilka, każdy będzie miał swój setStrokeDashoffset każdy z innymi wartościami

To można by rozwiązać przy pomocy Context API lub tworząc jakiś własny broadcaster, do którego każdy zainteresowany komponent by się podpinał przekazując jakiś identyfikator, po którym broadcaster by rozpoznawał do kogo wysłać poszczególne aktualizacje danych w razie wystąpienia eventu.

komentarz 29 stycznia 2021 przez hakiros54 Obywatel (1,160 p.)
tak, wszystko wyskakuje podczas scrollowania jak powinno, console.log w useEffect też działa i gdy daje listenera na click zamiast aos:in lub out, to też działa (w sensie, jest wiadomosc w konsoli). dodatkowo npm pokazuje, że mam aos wersje 6.14.8  (gdzieś w googlu znalazłem, że nie działa to dal wersji wcześniejszej niż chyba 3.0 czy jakoś tak).

Próbowałem też dodać listenera do documentu (document.addEventListener) a także do danego elemntu który ma wyskoczyć (document.querySelector(".asd").addEventListener (dodałem klase asd do tego elementu (jest tylko jeden na stronie z taką klasą więc nie jest to problem, że znajduje jakiś inny))) w żadnym wypadku aos mi się nie odpalał.
komentarz 29 stycznia 2021 przez ScriptyChris Mędrzec (190,190 p.)

npm pokazuje, że mam aos wersje 6.14.8  (gdzieś w googlu znalazłem, że nie działa to dal wersji wcześniejszej niż chyba 3.0 czy jakoś tak).

W jaki sposób odczytałeś to z npm - bo to bardziej wygląda na wersję samego npmNajnowsze wersje aos to 2.3.4 i 3.0.0-beta.6. Możesz pokazać plik package.json (jeśli jest obszerny, to wystarczą sekcje dependencies i devDependencies)?

Pokaż też jak podpinasz aos i w jaki sposób go inicjalizujesz. W issue na GitHub można przeczytać, że problemy z listenerem pojawiają się w starszej wersji biblioteki i gdy jest ona podpięta zbyt wcześnie w DOM.

komentarz 30 stycznia 2021 przez hakiros54 Obywatel (1,160 p.)

zainstalowałem za pomocą npm i aos, faktycznie jest wersja 2.3.4 


  "dependencies": {
    "@testing-library/jest-dom": "^5.11.9",
    "@testing-library/react": "^11.2.3",
    "@testing-library/user-event": "^12.6.0",
    "aos": "^2.3.4",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-redux": "^7.2.2",
    "react-scripts": "4.0.1",
    "redux": "^4.0.5",
    "uuid": "^8.3.2",
    "web-vitals": "^0.2.4"
  },

tutaj podpinam i inicjalizuje. Tak jak mówie, używam aos by elementy mi wyskakiwały w innych komponentach i tam działa (tutaj też tylko listener nie działa)

import React, { useEffect } from "react";
// TUTAJ
import Aos from "aos";
import "aos/dist/aos.css";

import Loading from "./components/Loading";
import Menu from "./components/Menu";
import AboutMe from "./components/AboutMe";
import Skills from "./components/Skills";
import Achievements from "./components/Achivements";
import Projects from "./components/Projects";
import Courses from "./components/Courses";
import Cv from "./components/Cv";
import Contact from "./components/Contact";



const App = () => {
	useEffect(() => {
       //TUTAJ
		Aos.init({ duration: 2000 });
         //TO NIE DZIAŁA ( jak daje samo console.log("asd") to też nie)
		document.querySelector(".asd").addEventListener('aos::in', ({ detail }) => {
			console.log('animated in', detail);
		});
		document.addEventListener('aos:out', ({ detail }) => {
			console.log('animated out', detail);
		});
	}, []);
	return (
		<main className="app">
			<Loading />
			<Menu />
			<AboutMe />
			<Achievements />
			<Skills />
			<Projects />
			<Courses />
			<Cv />
			<Contact />
		</main>
	);
}

export default App;

 

1 odpowiedź

0 głosów
odpowiedź 30 stycznia 2021 przez ScriptyChris Mędrzec (190,190 p.)

faktycznie jest wersja 2.3.4 

Sprawdziłbym więc trop wspomnianego issue na GitHub i zainstalował najnowszą wersję 3.0.0-beta.6. Będąc w katalogu projektu wykonaj w konsoli oba polecenia:

npm uninstall aos --save

npm install aos@3.0.0-beta.6 --save

Upewnij się, że w pliku package.json paczka aos ma teraz przypisaną najnowszą wersję.

Jeśli to nie pomoże, to możesz debugować kod: tutaj w kodzie źródłowym jest wywołanie eventu 'aos:in' (choć pewnie wyjściowo będzie zminifikowany, więc poszukaj frazy 'aos:in' w plikach zbudowanych paczek projektu w swoim IDE lub użyj opcji globalnego szukania w devtoolsach przeglądarki) i ewentualnie próbować zimplementować fix lub workaround, który nie będzie wymagał ingerencji w kod samej biblioteki; albo rozejrzyj się za inną biblioteką - swoją drogą ta biblioteka aos już raczej nie jest wspierana i ma 2 lata.

 (tutaj też tylko listener nie działa)

.addEventListener('aos::in'

Tam powinien być pojedynczy dwukropek → 'aos:in'.

Podobne pytania

0 głosów
0 odpowiedzi 272 wizyt
0 głosów
1 odpowiedź 217 wizyt
pytanie zadane 6 lipca 2022 w JavaScript przez zerakot Obywatel (1,870 p.)
+1 głos
1 odpowiedź 97 wizyt

92,537 zapytań

141,377 odpowiedzi

319,456 komentarzy

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

...