Próbuję przełączyć stan komponentu w ReactJS, ale pojawia się komunikat o błędzie:
Przekroczono maksymalną głębokość aktualizacji. Może się tak zdarzyć, gdy składnik wielokrotnie wywołuje funkcję setState wewnątrz komponentu componentWillUpdate lub componentDidUpdate. React ogranicza liczbę zagnieżdżonych aktualizacji, aby zapobiec nieskończonym pętlom.
Nie widzę nieskończonej pętli w moim kodzie, czy ktoś może pomóc?
Kod komponentu ReactJS:
import React, { Component } from 'react';
import styled from 'styled-components';
class Item extends React.Component {
constructor(props) {
super(props);
this.toggle= this.toggle.bind(this);
this.state = {
details: false
}
}
toggle(){
const currentState = this.state.details;
this.setState({ details: !currentState });
}
render() {
return (
<tr className="Item">
<td>{this.props.config.server}</td>
<td>{this.props.config.verbose}</td>
<td>{this.props.config.type}</td>
<td className={this.state.details ? "visible" : "hidden"}>PLACEHOLDER MORE INFO</td>
{<td><span onClick={this.toggle()}>Details</span></td>}
</tr>
)}
}
export default Item;
javascript
reactjs
react-native
Maja Okholm
źródło
źródło
this.toggle()
nathis.toggle
lub{()=> this.toggle()}
toggle(){...}
w,toggle = () => {...}
aby nie było potrzebybind
!Odpowiedzi:
że ponieważ wywołujesz toggle wewnątrz metody renderowania, co spowoduje ponowne renderowanie i przełączenie, wywoła ponownie i ponownie renderuje i tak dalej
ten wiersz w twoim kodzie
musisz
onClick
odwołać się dothis.toggle
tego, aby go nie nazywaćaby rozwiązać problem, zrób to
źródło
onClick={(param) => this.toggle(param)}
. To nie zostanie uruchomione natychmiast (i ponownie się wyłączy). To jest definicja wywołania zwrotnego (funkcja strzałki).onClick={() => this.toggle(param)}
onClick={(event) => this.toggle(event, myParam)}
.closeEditModal = () => this.setState({openEditModal: false});
Jak to wywołać w renderowaniu?Przy wywołaniu funkcji należy przekazać obiekt zdarzenia:
Jeśli nie potrzebujesz obsługi zdarzenia onClick, możesz również wpisać:
Teraz możesz również dodać swoje parametry w funkcji.
źródło
{<td><span onClick={() => this.toggle(whateverParameter)}>Details</span></td>}
Zapomnij najpierw o reakcji:
nie jest to związane z reagowaniem i pozwól nam zrozumieć podstawowe pojęcia Java Script. Na przykład napisałeś następującą funkcję w skrypcie java (nazwa to A).
P.1) Jak wywołać zdefiniowaną przez nas funkcję?
Ans: a ();
P.2) Jak przekazać odniesienie do funkcji, abyśmy mogli ją nazwać drugą?
Odp: niech zabawa = a;
Przechodząc do twojego pytania, użyłeś parantezy z nazwą funkcji, co oznacza, że funkcja zostanie wywołana, gdy zostanie wyświetlona następująca instrukcja.
Więc jak to poprawić?
Prosty!! Po prostu usuń nawiasy. W ten sposób dałeś odniesienie tej funkcji do zdarzenia onClick. Wywoła funkcję tylko wtedy, gdy zostanie kliknięty komponent.
Jedna sugestia wydana, aby zareagować:
Unikaj używania funkcji inline zgodnie z sugestią kogoś w odpowiedzi, może to spowodować problemy z wydajnością. Unikaj podążania za kodem, będzie tworzył instancję tej samej funkcji za każdym razem, gdy funkcja zostanie wywołana (instrukcja lamda tworzy nową instancję za każdym razem).
Uwaga: i nie ma potrzeby jawnego przekazywania zdarzenia (e) do funkcji. możesz uzyskać do niego dostęp w funkcji bez jej przekazywania.
https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578
źródło
Wiem, że ma wiele odpowiedzi, ale ponieważ większość z nich jest stara (no cóż, starsza), żadna nie wspomina o podejściu, na które bardzo szybko się rozwijam. W skrócie:
Użyj funkcjonalnych elementów i haczyków .
Dłużej:
Spróbuj użyć jak największej liczby komponentów funkcjonalnych zamiast klasowych, szczególnie do renderowania , ORAZ staraj się, aby były tak czyste, jak to tylko możliwe (tak, dane są domyślnie brudne, wiem).
Dwie wprost oczywiste zalety komponentów funkcjonalnych (jest ich więcej):
Szybki dowód na drugi punkt - czy to nie jest absolutnie obrzydliwe?
Jeśli używasz funkcjonalnych komponentów do więcej niż renderowania, będziesz potrzebować drugiej części świetnego duetu - haczyków. Dlaczego są lepsze niż metody cyklu życia, co jeszcze mogą zrobić i wiele więcej zajęłoby mi dużo miejsca, więc polecam posłuchać samego mężczyzny: Dan głosi haczyki
W takim przypadku potrzebujesz tylko dwóch haczyków:
Hak callback o dogodnej nazwie
useCallback
. W ten sposób zapobiegasz ciągłemu wiązaniu funkcji podczas ponownego renderowania.Hak stanu, wywoływany
useState
do utrzymywania stanu, mimo że cały komponent jest funkcjonalny i wykonywany w całości (tak, jest to możliwe dzięki magii zaczepów). Wewnątrz tego haka będziesz przechowywać wartość toggle.Jeśli czytasz tę część, prawdopodobnie chcesz zobaczyć wszystko, o czym mówiłem w akcji i zastosowałem do pierwotnego problemu. Proszę bardzo: Demo
Dla tych z Was, którzy chcą tylko rzucić okiem na komponent, a WTF jest o tym, oto jest:
PS: Napisałem to na wypadek lądowania tu wielu ludzi z podobnym problemem. Miejmy nadzieję, że spodoba im się to, co widzą, przynajmniej na tyle dobrze, że będą go bardziej wygooglować. To nie ja mówię, że inne odpowiedzi są błędne, to ja mówię, że odkąd zostały napisane, istnieje inny sposób (IMHO, lepszy) radzenia sobie z tym.
źródło
jeśli nie musisz przekazywać argumentów do funkcji, po prostu usuń () z funkcji, jak poniżej:
ale jeśli chcesz przekazywać argumenty, powinieneś zrobić jak poniżej:
źródło
ReactJS: Błąd maksymalnej głębokości aktualizacji przekroczony
Dlaczego to?
źródło
Jeśli chcemy przekazać argument w wywołaniu, musimy wywołać metodę jak poniżej Ponieważ używamy funkcji strzałkowych, nie ma potrzeby wiązania metody w
cunstructor
.kiedy łączymy metodę w konstruktorze w ten sposób
następnie musimy wywołać metodę bez przekazywania żadnego argumentu, jak poniżej
i próbujemy przekazać argument podczas wywoływania funkcji, jak pokazano poniżej, wtedy błąd pojawia się jak przekroczona maksymalna głębokość.
źródło
onClick powinieneś wywołać funkcję, która nazywa się przełącznikiem funkcji.
onClick={() => this.toggle()}
źródło
W tym przypadku ten kod
powoduje natychmiastowe wywołanie funkcji toggle i ponowne jej renderowanie, w ten sposób wykonując nieskończone wywołania.
więc przekazanie tylko odniesienia do tej metody przełączania rozwiąże problem.
więc ,
będzie kod rozwiązania.
Jeśli chcesz użyć (), powinieneś użyć funkcji strzałki, takiej jak ta
Jeśli chcesz przekazać parametry, powinieneś wybrać ostatnią opcję i możesz przekazać takie parametry
W ostatnim przypadku nie wywołuje natychmiast i nie powoduje ponownego renderowania funkcji, stąd unika się nieskończonych wywołań.
źródło