Wpis z mikrobloga

Witam, mam pytanie. Bo chyba nie do końca rozumiem dlaczego tak to działa. Nakreślę wpierw sytuację. Wygląda skomplikowanie, ale pewnie chodzi o banał - zwykły conditionalRendering.

Bardzo prosty conditionalRendering.

Form > a w środku textArea i button

Nakreślę kod.

` const [openNote, setOpenNote] = useState(false);

// no i rendering na zasadzie toogle // kod to tylko zarys - podstawy podstaw. także bez szczegółów

{openNote && ( ) } ....

{!openNote && ({
setOpenNote ( true )

} } ) } ....

I teraz całe zamieszanie Form Posiada na sobie OutsideClicka - custom hooka który bierze refa czyli naszego forma i sprawdza jeśli jest outside click to robi Callbacka, w tym przypadku po prostu ukrywa Forma.

I o co całe zamieszanie ?

Patrząc na conditional wyżej, button ukrywa się w momencie pokazania textArea - > on go nie toogluje, tylko pokazuje a sam znika.

Sprawdziłem sobie kolejność wywołania funkcji po kliknieciu i wygląda to tak:

1. handleToogle zmiana statu
2. rerenderkomponenu
3.UWAGA ! odpala outsideClicka >> dziwne ?

Co za tym idzie zamiast tooglować / pokazywać mi textArea i ukrywać button zamyka mi całego forma.

Żeby nie było że jestem głupi i nie szukałem o co kaman.
Sprawdziłem e.target =>
event wychodzi z elementu button ( span ), czyli naszego buttona.

Patrząc na atrybuty nodowskie ukrywanie klikniętego buttona powoduje że
ofSetParent : null

a powinien być :

offsetParent:

I o co kaman ? Czy chodzi o kwestie onClick ?

Gdy buttona nie chowam nie ma żadnego problemu. Wygląda tak jakby najpierw mi go chował a później wykrył onClick z outsideClickHooka

#react #javascript #programowanie
  • 13
@cppguy:

https://codesandbox.io/s/nervous-dewdney-de0qy?file=/src/App.js

Problem raczej w tym że btn do pokazywania textArea po kniknięciu nie jest w drzewie elementu REF i traktuje go wtedy jako spełniony warunek w outsideClick, i zamyka mi forma.

Forma zrobiłem jako diva, ale to jeden ciul.

Mógłbym po prostu chować go poprzez display, nie usuwać go z drzewa, ale chciałbym zrozumieć z czym to jest związane. Z charakterystyką wywołania funkcji czy z charakterystyką wywołania event on click.
@NiewzruszonaMasa: generalnie to chyba specyfika addEventListener i momentu w którym event zostanie przechwycony: https://www.quirksmode.org/js/events_order.html#link4

Jeśli w Twoim przykładzie, w useEventListener ustawisz flagę useCapture w addEventListener na true ( https://developer.mozilla.org/pl/docs/Web/API/EventTarget/addEventListener ), to osiągniesz zamierzony efekt - callback przekazany do addEventListener zostanie wywołany przed onClick bezpośrednio na przycisku.
@NiewzruszonaMasa: Click event propaguje w górę drzewa i odpala click handler na dokumencie i dlatego form znika. Jeśli przekażesz event i odpalisz stopPropagation to chyba wszystko działa OK

{
e.stopPropagation()
setOpenNote(true);
}}
>


Ewentualnie mozesz odpalić event w fazie capture kiedy idzie od dokumentu do buttona a nie od buttona do dokumentu
@icoztego: W moim przykładzie chodzi o to że klikam na Show i znika form, a według zamysłu powinien zniknąć tylko button. Faza capture przerzucona na listenera wew outsideClicka - rozwiązała problem.

działa, śmiga fajnie - ale muszę ogarnąć. Niby proste elementarne rzeczy ale mam jest podobny problem w trochę bardziej skomplikowanym przykładzie.

events order się kłania - pamiętałem o tym, ale jak pisze się kod to później ciężko samą teorie na
Twój button jest wewnątrz "document" do którego dodajesz click handler (click outside). Event idzie od buttona i wywoływany jest na każdym rodzicu. Więc jak klikasz button "show" to znika button i pojawia się textarea ale potem jest wywoływany click handler na dokumencie który ukrywa formularz. Dlatego jak klikniesz potem show form to jest już textarea a nie button. Obydwa handlery zadziałały i zrobiły to co miały zrobić.

To co chcesz działa dobrze
@icoztego: Sorry że dalej o to męczę.
https://codesandbox.io/s/cocky-noyce-h98ro?file=/src/App.js

"Więc jak klikasz button "show" to znika button i pojawia się textarea ale potem jest wywoływany click handler na dokumencie który ukrywa formularz."

ale dokładnie ukrywa, dlatego że btnShow ten z useState nie jest częścią drzewa form ?

Zauważ że btnShow cały czas jest częścią drzewa form, gdzie warunek w outsideclick nie zostaje spełniony. Rozumiem twoje spostrzeżenie ale chcę być pewien że to
@icoztego: Tylko nie wiem czy faktycznie dlatego, sprawdziłem kolejność wywołania funkcji bez capture i faktycznie callback najpierw ukrywa button by później odpalić outsideClick. Captur zamienia kolejność wywołania funkcji, ogólnie sporo artów na temat sposobu wykonywania kolejności wywołań jest. Wiadomo nie ma się co spuszczać na tym, ale jak będę miął chwile to wrzucę tu bardziej #!$%@? przykład, bo z tymi wywołania są niezłe jajca czasami. Zwłaszcza gdy manipuluje się domem w
@NiewzruszonaMasa: Wyglada na to ze to działa tak:

Klikniecie w button
Render bez buttona
Event na dokumencie

dlatego nie działa tak jak wydaje się że powinno. Jeśli miałbym obstawiać to problem sprowadza się chyba do tego że onClick to nie jest natywny event (tak jak onclick w js) tylko coś co React nazywa SyntheticEvent. Dlatego jest to obsługiwane w innej kolejności niż natywny event. Ale to taki strzał w ciemno i
@icoztego: pewnie seniorzy się z nas śmieją, ale jajca jak #!$%@? :) Tzn wszystko jest logiczne, ale kto by pomyślał ze nad głupim ewentem się można parę dni pospuszcząć ( ͡° ͜ʖ ͡°) ogólnie to stronka podana wyżej wiele wyjaśnia. + dokładnie tak jak piszesz.