Lifting State Up: Jak komponenty React Child komunikują się z rodzicami
React używa jednokierunkowego przepływu danych od rodzica do dziecka, nigdy od dziecka do rodzica. Ale co się dzieje, gdy element potomny musi komunikować się ze swoim rodzicem?
Zdobądź wiedzę niezbędną do podniesienia statusu elementu podrzędnego, umożliwiając mu przesyłanie informacji do komponentu nadrzędnego.
Komponenty w React
React ustanawia hierarchiczną strukturę poprzez umieszczenie komponentów podrzędnych w obrębie odpowiednich komponentów nadrzędnych, tworząc w ten sposób podstawę wizualnej reprezentacji aplikacji.
<ParentComponent>
<ChildComponent/>
</ParentComponent>
W hierarchicznej strukturze komponentów w Reakcie, każdy podrzędny element jest wyposażony w określone informacje, które są określane jako rekwizyty. Rekwizyty te mogą składać się z tablicy, obiektu, ciągu znaków lub funkcji i są przekazywane przez komponent nadrzędny do komponentu podrzędnego. Nie jest możliwe, aby komponent podrzędny bezpośrednio zmieniał te rekwizyty.
Rozważmy następujący komponent o nazwieCounterButton:
const CounterButton = () => {
const [count, setCount] = useState(0)
const handleIncrement = () => {
setCount(count \\+ 1)
}
return (
<button onClick={handleIncrement}>Increment</button>
)
}
Komponent zachowuje indeks o nazwie count
, który jest zwiększany po każdym kliknięciu przycisku przez użytkownika.
Rozważmy scenariusz, w którym komponent CounterButton jest objęty dodatkowym komponentem o nazwie Home, a ponadto wyobraźmy sobie, że integracja ta odbywa się w szerszym kontekście tworzenia lub projektowania oprogramowania.
const Home = () => {
return (
<CounterButton/>
)
}
Aby wyświetlić wartość zliczania pochodzącą z komponentu CounterButton w kontekście komponentu Home, można napotkać przeszkodę.
Zgodnie z ustalonym paradygmatem, React nakazuje jednokierunkową propagację danych z elementów nadrzędnych do odpowiadających im komponentów podrzędnych. W związku z tym komponent CounterButton nie może bezpośrednio uzyskiwać dostępu do pochodnej wartości stanu licznika i udostępniać jej komponentowi Home w hierarchii aplikacji.
Aby rozwiązać ten problem, konieczne jest przeniesienie stanu na wyższy poziom abstrakcji lub kontekstu.
Jak podnieść stan w celu udostępniania danych między komponentami
Czynność podnoszenia wewnętrznej konfiguracji lub danych komponentu, często określana jako “podnoszenie stanu”, polega na podniesieniu jego stanu na wyższy poziom w hierarchii komponentów poprzez przeniesienie go do wspólnego przodka lub komponentu nadrzędnego. Pozwala to na dystrybucję tych informacji do elementów potomnych poprzez dostarczenie wartości właściwości.
Aby rozwiązać problem poruszony w poprzednim przykładzie, konieczne jest przeniesienie stanu licznika i funkcji handleIncrement w komponencie Home.Wymaga to przekazania funkcji handleIncrement jako właściwości do komponentu CounterButton.
const Home = () => {
const [count, setCount] = useState(0)
const handleIncrement = () => {
setCount(count\\+\\+)
}
return (
<CounterButton handlerIncrement={handleIncrement]/>
<p>{count}</p>
)
}
Aby zaktualizować komponent CounterButton w celu dostosowania funkcji handleIncrement i wywołania jej podczas interakcji użytkownika, wykonaj następujące kroki:1. Przekaż funkcję handleIncrement jako właściwość do komponentu CounterButton z jego komponentu nadrzędnego. Pozwoli to komponentowi podrzędnemu uzyskać dostęp do funkcji i wykorzystać ją do inkrementacji licznika.2. W komponencie CounterButton dodaj detektor zdarzeń, który nasłuchuje zdarzeń kliknięcia na elemencie przycisku. Po wykryciu zdarzenia kliknięcia, uruchom funkcję handleIncrement, wywołując ją z odpowiednimi argumentami (np. przekazując this i wszelkie wymagane parametry).3. Upewnij się, że komponent CounterButton ma dostęp do zmiennych stanu powiązanych z wartością licznika, aby mógł wyświetlać lub aktualizować bieżący stan licznika. Jeśli to konieczne, przekaż odpowiednie
const CounterButton = ({handleIncrement}) => {
return (
<button onClick={handleIncrement}>Increment</button>
)
}
Centralizując dane i przejmując odpowiedzialność za zarządzanie nimi, podnoszenie stanu skutecznie przenosi ten ciężar z dziecka na rodzica.
Podniesienie stanu może służyć podwójnemu celowi, ułatwiając wyświetlanie danych w komponencie nadrzędnym, a jednocześnie umożliwiając płynną synchronizację danych w wielu komponentach podrzędnych.
Aby ułatwić współdzielenie danych między komponentem nadrzędnym a jego komponentami podrzędnymi, zarówno komponent nagłówka, jak i stopki są umieszczone w tym komponencie nadrzędnym. Co więcej, każdy z tych komponentów wyświetla wspólną liczbę, która jest wymagana przez oba elementy. W celu propagacji tej informacji od elementu nadrzędnego do elementów podrzędnych, jednym z podejść byłoby przekazanie wspólnej liczby jako argumentu w postaci rekwizytów.
const Home = () => {
const [count, setCount] = useState(0)
const handleIncrement = () => {
setCount(count\\+\\+)
}
return (
<Header count={count}/>
<CounterButton handlerIncrement={handleIncrement]/>
<Footer count={count}/>
)
}
Niemniej jednak ważne jest, aby zachować ostrożność podczas podnoszenia świadomości, aby uniknąć znalezienia się w sytuacji określanej jako “wiercenie rekwizytów”.
The Prop Drilling Challenge
Wraz ze wzrostem złożoności aplikacji może okazać się konieczne, aby różne komponenty znajdujące się dalej w hierarchii komponentów miały dostęp do współdzielonych danych. Aby ułatwić taki dostęp, należy przekazywać wspomniane informacje za pośrednictwem elementów pośrednich. Jednak nadmierne poleganie na przekazywaniu właściwości przez wiele warstw jest znane jako “prop drilling”, co może prowadzić do niepożądanych komplikacji i nadmiarowości w bazie kodu.
Implementacja właściwości w językach programowania może skutkować wyzwaniami związanymi z monitorowaniem przepływu informacji, prowadząc do złożonych i uciążliwych działań konserwacyjnych dla twórców oprogramowania.
Aby złagodzić kwestię propagacji znoju, a jednocześnie ułatwić dostęp do współdzielonych informacji w różnych elementach, odpowiednim rozwiązaniem jest wykorzystanie kontekstu React. Stosując tę metodologię, można skoncentrować stan w scentralizowanej lokalizacji, dzięki czemu pozostaje on dostępny przez cały czas działania aplikacji.
Współdzielenie danych w React przy użyciu rekwizytów
Aby przekazać informacje z elementu podrzędnego do jego komponentu nadrzędnego, konieczne jest podniesienie statusu jednostki podrzędnej do poziomu jednostki nadrzędnej i przekazanie funkcji modyfikującej status do jednostki podrzędnej za pomocą projekcji.
Gdy komponent potomny znajduje się na znacznej głębokości w hierarchicznej strukturze komponentów, zaleca się zastosowanie React Context lub zewnętrznego rozwiązania, takiego jak React Redux, do zarządzania stanem, aby uniknąć praktyki przekazywania wielu rekwizytów przez wiele poziomów zagnieżdżenia, znanej jako “wiercenie rekwizytów”.