Jak zdebugować zepsutą kolejność hooków?

0

Mam bardzo dużą aplikację w Reactcie (dokładniej React Native), i raz na jakiś czas w losowych momentach dostaję warning, że zmieniła się kolejność hooków. Dostaję jakiś stacktrace, ale ten stacktrace w ogóle nie jest pomocny - są same link do generycznych widoków i komponentów z node_modules/.

Nie sądzę że bug jest w jakiejś zależności - myślę że w aplikacji ktoś się gdzieś pomylił.

Jaki jest sposób żeby jakoś sensownie znaleźć miejsce gdzie jest źle użyty hook?

1

A jakbyś nie renderował całej aplikacji naraz, tylko np. poddrzewo? wtedy zobaczyłbyś, które poddrzewo całej aplikacji zgłasza ten błąd. Wtedy znowu sprawdzić podddrzewo poddrzewa itp.

Żeby wyizolować komponent albo chociaż poddrzewo, gdzie jest ten błąd.

0
LukeJL napisał(a):

A jakbyś nie renderował całej aplikacji naraz, tylko np. poddrzewo? wtedy zobaczyłbyś, które poddrzewo całej aplikacji zgłasza ten błąd. Wtedy znowu sprawdzić podddrzewo poddrzewa itp.

Żeby wyizolować komponent albo chociaż poddrzewo, gdzie jest ten błąd.

To mi się wydaje bardzo "po chłopsku" i ręcznie. Poza tym, ta aplikacja ma bardzo dużo komponentów.

Ja szukam jakiegoś gotowego automatycznego rozwiązania.

1

jest coś takiego jak reguła do Eslinta, która sprawdza czy hooki są poprawnie napisane: https://www.npmjs.com/package/eslint-plugin-react-hooks

0
LukeJL napisał(a):

jest coś takiego jak reguła do Eslinta, która sprawdza czy hooki są poprawnie napisane: https://www.npmjs.com/package/eslint-plugin-react-hooks

Ale to z defaulta działa tylko z domyślnymi hookami. U nas w aplikacji jest bardzo dużo customowych hooków, i je trzeba wyspecyfikować osobno, więc to odpada.

2

"Nieprawidłowa kolejność hooków" oznacza taki przypadek, gdy jeden z hooków nie jest używany za każdym razem?

const Error = () => {
  const [value, setValue] = useState(false);

  if (value) {
    useEffect(() => {
      console.log('...');
    }, []);
  }

  return <button onClick={() => setValue(!value)}>Odśwież komponent</button>;
};

Oczywiście sposobem na naprawę błędu jest zrobienie warunku wewnątrz useEffect, ale w bardziej skomplikowanych przypadkach możemy podzielić hooki na jeszcze mniejsze części. Wszystkie rzeczy, które nie potrzebują stanu można wynieść "wyżej" poza hook i w nim używać jedynie rzeczy, które są konieczne useState, useEffect, useReducer itd

const customAction = (value) => {
  // fragment kodu, który nie potrzebuje polegać na stanie Reacta
  // i wystarczą mu zwykłe argumenty
}

const useMyHook = () => {
  // fragment kodu wykorzystujący hooki i wywołujący powyższą funkcję w odpowiednim momencie
}

LukeJL napisał(a):

A jakbyś nie renderował całej aplikacji naraz, tylko np. poddrzewo? wtedy zobaczyłbyś, które poddrzewo całej aplikacji zgłasza ten błąd. Wtedy znowu sprawdzić podddrzewo poddrzewa itp.

Żeby wyizolować komponent albo chociaż poddrzewo, gdzie jest ten błąd.

Przy tym pomyśle można byłoby wykorzystać Reactowy "try / catch". Jest to taki specjalny komponent, który przechwytuje błędy z komponentów, które renderuje i w razie błędu pozwala jakoś na to zareagować np zmienić renderowane komponenty.

0

@Xarviel: Super że się rozpisałeś; ale w jaki sposób ma to kogokolwiek przybliżyć do znalezienia faktycznego miejsca gdzie taki błędny hook jest?

Reactowy "try / catch", to już dawno zrobiłem - i mam stacktrace, tylko że stacktrace nie jest pomocny bo jest w nim połowa wpisów z bibliotek reacta a połowa z generycznych komponentów - ni jak mnie to nie przybliża do znalezienia konkretnego miejsca.

1

Rozpisałem się, ponieważ "zepsuta kolejność hooków" nic mi początkowo nie mówiła, więc chciałem się upewnić, czy mówimy o tym samym i to stanowi połowę mojego wcześniejszego posta.

Reactowy "try / catch", to już dawno zrobiłem - i mam stacktrace, tylko że stacktrace nie jest pomocny bo jest w nim połowa wpisów z bibliotek reacta a połowa z generycznych komponentów - ni jak mnie to nie przybliża do znalezienia konkretnego miejsca.

Głównie mi chodziło o możliwość wyrenderowania innego komponentu w przypadku błedu, bo takich komponentów "error boundary" może być kilka / kilkanaście podzielonych na konkretne sekcje aplikacji. Wyłącza się sekcja A, ale działa sekcja B, C, D, czyli błąd jest w A. Sekcja A jest za duża żeby znaleźć przyczynę? To wtedy dzielę sekcje A na jeszcze mniejsze części, aż do znalezienia problemu.

I tak, wiem, mówileś, że takie rozwiązanie Cię nie interesuje, ale nie kojarzę, aby React udostępniał jakieś inne mechanizmy do tego. Jedynie powstał plugin do Eslinta, ale z każdym nowym hookiem, który stworzymy trzeba byłoby modyfikować ustawienia reguły.

0
Xarviel napisał(a):

Rozpisałem się, ponieważ "zepsuta kolejność hooków" nic mi początkowo nie mówiła, więc chciałem się upewnić, czy mówimy o tym samym i to stanowi połowę mojego wcześniejszego posta.

Reactowy "try / catch", to już dawno zrobiłem - i mam stacktrace, tylko że stacktrace nie jest pomocny bo jest w nim połowa wpisów z bibliotek reacta a połowa z generycznych komponentów - ni jak mnie to nie przybliża do znalezienia konkretnego miejsca.

Głównie mi chodziło o możliwość wyrenderowania innego komponentu w przypadku błedu, bo takich komponentów "error boundary" może być kilka / kilkanaście podzielonych na konkretne sekcje aplikacji. Wyłącza się sekcja A, ale działa sekcja B, C, D, czyli błąd jest w A. Sekcja A jest za duża żeby znaleźć przyczynę? To wtedy dzielę sekcje A na jeszcze mniejsze części, aż do znalezienia problemu.

No czyli ręcznie. Pisałem o tym w pierwszym poście, że na takie coś wpadłem sam, i szukam jakiegoś automatycznego rozwiązania.

Ale dzięki za odpowiedź.

1 użytkowników online, w tym zalogowanych: 0, gości: 1