Gdy zmienia się stan składnika reagującego, wywoływana jest metoda renderowania. Dlatego w przypadku każdej zmiany stanu można wykonać akcję w ciele metod renderowania. Czy istnieje zatem szczególny przypadek użycia dla wywołania zwrotnego setState?
191
render()
zamiast tego wstawisz tę funkcję , będzie ona działać za każdym razem, gdy DOWOLNY stan zostanie zaktualizowany, co prawdopodobnie nie jest tym, czego chcesz. Dzięki temu Twój kod będzie mniej czytelny i logiczny.Odpowiedzi:
Tak, ponieważ
setState
działa w pewienasynchronous
sposób. Oznacza to, że po wywołaniusetState
dothis.state
zmiennej nie jest natychmiast zmienić. więc jeśli chcesz wykonać akcję natychmiast po ustawieniu stanu na zmienną stanu, a następnie zwrócić wynik, przydatne będzie wywołanie zwrotneRozważ poniższy przykład
Powyższy kod może nie działać zgodnie z oczekiwaniami, ponieważ
title
zmienna mogła nie zostać zmutowana przed wykonaniem na niej sprawdzania poprawności. Teraz możesz się zastanawiać, czy możemy przeprowadzić walidację wrender()
samej funkcji, ale byłby lepszy i czystszy sposób, gdybyśmy mogli sobie z tym poradzić w samej funkcji changeTitle, ponieważ dzięki temu twój kod byłby bardziej zorganizowany i zrozumiały.W takim przypadku przydatne jest oddzwonienie
Innym przykładem będzie sytuacja, gdy chcesz
dispatch
i działanie, gdy stan się zmieni. będziesz chciał to zrobić w trybie oddzwaniania, a nie w takirender()
sposób, w jaki będzie on wywoływany za każdym razem, gdy nastąpi ponowne wyrenderowanie, a zatem istnieje wiele takich scenariuszy, w których będziesz potrzebował oddzwonienia.Innym przypadkiem jest
API Call
Może się zdarzyć, że konieczne będzie wywołanie interfejsu API na podstawie konkretnej zmiany stanu, jeśli zrobisz to w metodzie renderowania, będzie ona wywoływana przy każdej
onState
zmianie renderowania lub dlatego, że niektóre Prop przeszły naChild Component
zmienioną.W takim przypadku należy użyć a,
setState callback
aby przekazać zaktualizowaną wartość stanu do wywołania APIźródło
if (this.title.length === 0) {
powinno byćthis.state.title.length
, prawda?setState(state => state.title.length ? { titleError: "Title can't be blank" } : null)
a zmiany zostaną nałożone. Nie ma potrzeby podwójnego renderowania.źródło
1. przypadek użycia, który przychodzi mi na myśl, to
api
wywołanie, które nie powinno przejść do renderowania, ponieważ będzie działać w celueach
zmiany stanu. Wywołanie interfejsu API powinno być wykonywane tylko przy specjalnej zmianie stanu, a nie przy każdym renderowaniu.Bardzo zła praktyka , ponieważ
render
-metoda powinna być czysta, oznacza to, że nie należy wykonywać żadnych akcji, zmian stanu, wywołań interfejsu API, po prostu skomponuj swój widok i zwróć go. Działania należy wykonywać tylko w przypadku niektórych zdarzeń. Renderowanie nie jest zdarzeniem, alecomponentDidMount
na przykład.źródło
Rozważ połączenie setState
POMYSŁ
Więc nie możesz polegać
this
. Jeśli powyższe wywołanie zostało wykonane wewnątrz funkcji asynchronicznejthis
, odniesie się do stanu komponentu w tym momencie czasu, ale spodziewaliśmy się, że odniesie się to do właściwości wewnątrz stanu w czasie wywołania setState lub rozpoczęcia zadania asynchronicznego. Ponieważ zadaniem było wywołanie asynchroniczne, właściwość mogła się z czasem zmienić. Dlatego nie można wiarygodnie użyćthis
słowa kluczowego w odniesieniu do niektórych właściwości stanu, dlatego używamy funkcji zwrotnej, której argumentami są previousState i rekwizyty, co oznacza, kiedy zadanie asynchroniczne zostało wykonane i nadszedł czas na aktualizację stanu za pomocą wywołania setState prevState będzie odnosić się do stanu teraz, gdy setState jeszcze się nie zaczął Zapewnienie niezawodności, że nextState nie zostanie uszkodzony.Błędny kod: prowadziłby do uszkodzenia danych
Poprawny kod z setState z funkcją oddzwaniania:
Dlatego za każdym razem, gdy potrzebujemy zaktualizować nasz obecny stan do następnego stanu na podstawie wartości posiadanej przez właściwość właśnie teraz, a wszystko to dzieje się w sposób asynchroniczny, dobrym pomysłem jest użycie setState jako funkcji wywołania zwrotnego.
Próbowałem to wyjaśnić tutaj codepen CODE PEN
źródło