Mam składnik funkcjonalny, który inicjuje stan za pomocą useState, a następnie ten stan jest zmieniany za pośrednictwem pola wejściowego.
Następnie mam haczyk useEffect symulujący componentWillUnmount, dzięki czemu przed odłączeniem komponentu bieżący, zaktualizowany stan jest rejestrowany w konsoli. Jednak stan początkowy jest rejestrowany zamiast bieżącego.
Oto prosta reprezentacja tego, co próbuję zrobić (to nie jest mój rzeczywisty komponent):
import React, { useEffect, useState } from 'react';
const Input = () => {
const [text, setText] = useState('aaa');
useEffect(() => {
return () => {
console.log(text);
}
}, [])
const onChange = (e) => {
setText(e.target.value);
};
return (
<div>
<input type="text" value={text} onChange={onChange} />
</div>
)
}
export default Input;
Inicjalizuję stan jako „początkowy”. Następnie używam pola wprowadzania, aby zmienić stan, powiedzmy, że wpisuję „nowy tekst”. Jednak gdy komponent jest odłączany, w konsoli rejestrowane jest „początkowe” zamiast „nowego tekstu”.
Dlaczego to się dzieje? Jak mogę uzyskać dostęp do aktualnego zaktualizowanego stanu po odmontowaniu?
Wielkie dzięki!
Edytować:
Dodanie tekstu do tablicy zależności useEffect nie rozwiązuje mojego problemu, ponieważ w moim scenariuszu w świecie rzeczywistym chcę uruchomić akcję asynchroniczną w oparciu o bieżący stan i nie byłoby to efektywne za każdym razem, gdy „ tekst ”zmienia się stan.
Szukam sposobu, aby uzyskać bieżący stan tylko tuż przed odłączeniem komponentu.
2 odpowiedzi
Skutecznie zapamiętałeś początkową wartość stanu, więc kiedy komponent odmontuje tę wartość jest tym, co zwrócona funkcja objęła swoim zasięgiem.
Funkcja czyszczenia jest uruchamiana przed usunięciem składnika z interfejsu użytkownika aby zapobiec wyciekom pamięci. Ponadto, jeśli składnik renderuje wiele plików razy (jak to zwykle robią), poprzedni efekt jest czyszczony wcześniej wykonanie następnego efektu . W naszym przykładzie oznacza to nowy plik subskrypcja jest tworzona przy każdej aktualizacji. Aby uniknąć wypalenia efektu każda aktualizacja, patrz następna sekcja.
Aby uzyskać najnowszy stan, gdy wywoływana jest funkcja czyszczenia, musisz dołączyć text
do tablicy zależności, aby funkcja została zaktualizowana.
Dokumentacja dotycząca efektów
Jeśli przekażesz pustą tablicę (
[]
), właściwości i stan wewnątrz efektu zawsze będą miały swoje początkowe wartości . Podczas mijania[]
jako drugi argument jest bliższy znanemucomponentDidMount
i Model mentalnycomponentWillUnmount
, zwykle są lepsze rozwiązania aby uniknąć zbyt częstego ponownego uruchamiania efektów.
Oznacza to, że zwrócona funkcja „cleanup” nadal ma dostęp tylko do stanu i właściwości poprzedniego cyklu renderowania.
EDYTUJ
useRef
zwraca zmienny obiekt ref, którego właściwością jest.current
zainicjowany do przekazanego argumentu (initialValue
). Zwrócony obiekt będzie trwać przez cały okres użytkowania komponentu....
Przydaje się przy zachowaniu wszelkich zmiennych wartości , podobnie jak w przypadku używania pól instancji w klasach.
Użycie ref pozwoli ci zbuforować bieżące odniesienie text
, do którego można uzyskać dostęp w ramach funkcji czyszczenia.
/ EDYTUJ
Składnik
import React, { useEffect, useRef, useState } from 'react';
const Input = () => {
const [text, setText] = useState('aaa');
// #1 ref to cache current text value
const textRef = useRef(null);
// #2 cache current text value
textRef.current = text;
useEffect(() => {
console.log("Mounted", text);
// #3 access ref to get current text value in cleanup
return () => console.log("Unmounted", text, "textRef", textRef.current);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
console.log("current text", text);
return () => {
console.log("previous text", text);
}
}, [text])
const onChange = (e) => {
setText(e.target.value);
};
return (
<div>
<input type="text" value={text} onChange={onChange} />
</div>
)
}
export default Input;
Dzięki console.log w zwróconej funkcji czyszczenia zauważysz, że po każdej zmianie danych wejściowych poprzedni stan jest rejestrowany w konsoli.
W tym demo zarejestrowałem aktualny stan w efekcie i poprzednim stanie w funkcji czyszczenia. Zwróć uwagę, że funkcja czyszczenia rejestruje najpierw dziennik przed bieżącym dziennikiem następnego cyklu renderowania.
Musisz zdać text
do useEffect
useEffect(() => {
return () => {
console.log(text);
};
}, [text]);
Podobne pytania
Nowe pytania
reactjs
React to biblioteka JavaScript do tworzenia interfejsów użytkownika. Wykorzystuje deklaratywny paradygmat oparty na komponentach i ma być zarówno wydajny, jak i elastyczny.