Niestandardowy hak do wyciągania React odstaje na krok

0

Pytanie

Tworzę swój własny hak próbkowania dla uzyskania, jak i wysyłania danych. Śledzę oficjalnych dokumentów React do tworzenia własnych haczyków próbki, ale wygląda na to, że moje zmienne stanu, zwracane szydełku, udaje się na jeden krok z asynchronicznego zachowania useState. Oto mój własny hak do użytku

export const useMutationAwait = (url, options) => {
  const [body, setBody] = React.useState({});
  const [data, setData] = React.useState(null);
  const [error, setError] = React.useState(null);
  const [isLoading, setIsLoading] = React.useState(false);

  React.useEffect(() => {
    const fetchData = async () => {
      setError(null);
      setIsLoading(true);
      console.log("...fetching");
      try {
        const response = await axiosInstance.post(url, body, options);
        setData(response.status);
      } catch (error) {
        console.error(error.response.data);
        setError(error.response.data);
      }
      setIsLoading(false);
    };
    fetchData();
  }, [body]);

  return [{ data, isLoading, error }, setBody];
};

I używam go w swoim komponencie tak (w uproszczeniu) - gdy użytkownik kliknie przycisk rejestracji, chcę mieć możliwość natychmiast zdecydować, czy mój post jest udany, czy nie, i w związku z tym albo przejść do innego ekranu, albo wyświetl błąd próbkowania.

const [email, setEmail] = React.useState('');
const [password, setPassword] React.useState('');
const [{ data: mutData, error: mutError }, sendPost] =
    useMutationAwait("/auth/pre-signup");
  
const registerUser = async () => {
    sendPost({
      email,
      password,
    }); ---> here I want to evaluate the result but when I log data and error, the results come after second log (at first they are both null as initialised in hook)

Czy jest to w ogóle właściwym podejściem, którego staram się osiągnąć? W zasadzie, chcę stworzyć jakąś uniwersalną funkcję do pobierania danych i do zmiany danych i pomyślałem, że haki mogą być odpowiednim sposobem.

axios fetch react-hooks react-native
2021-11-22 19:27:10
2
0

Twoje podejście nie jest błędny, ale kod, którym dzielisz wydaje się niekompletne lub, być może, jest przestarzałe? Woła sendPost wystarczy odświeżyć jakiś stan wewnątrz swojego haka, ale, zakładając, że jego wywołanie zwróci obietnica (zapytanie na publikację), trzeba po prostu użyć async-await i owinąć go w instrukcji try-catch.

export const useMutationAwait = (url, options) => {
  const sendPost = async (body) => {
    // submit logic here & return request promise
  }
}
const registerUser = async () => {
  try {
    const result = await sendPost({ login, password });
    // do something on success
  } catch (err) {
    // error handling
  }
}

Niektóre zalecenia, ponieważ można wdrożyć swój własny hak, można realizować jeden, który tylko pobiera dane, a drugi, który tylko wysyła żądania (PUBLIKUJE). W ten sposób można zyskać więcej swobody, ponieważ niektóre strony będą mieć tylko GET, podczas gdy inne będą PUBLIKOWAĆ lub UMIESZCZAĆ. W zasadzie przy realizacji haka spróbuj zrobić to bardzo specyficzne dla jednego rozwiązania.

2021-11-22 20:22:36

Tak, próbowałem tej metody, ale chciałem mieć wszystkie zmienne { dane, pobieranie, błąd, [i, być może, funkcja mutacji?] = useMutation(punkt końcowy, ciało), która jest zwracana przez wywołanie połączenia.
Adam Martiška
0

Masz rację, wspominając o charakterze asynchronicznym aktualizacji stanu, ponieważ w tym główny problem, z którym można się zmierzyć.

Dzieje się następujący:

  • Aktualizujesz stan z pomocą sendPost wewnątrz funkcji.
  • Aktualizacje stanu reakcje ograniczone obszarem działania. Oznacza to, że React uruchamia wszystkie setState() wyzwania, które znajdzie się w określonej funkcji, wykonywane są dopiero po zakończeniu działania funkcji. Cytat z tego wydania:

Reagowanie na aktualizacje statusu pakietów, które odbywają się w modułach obsługi zdarzeń i metod cyklu życia. Tak więc, jeśli kilka razy aktualizacji stanu w obsłudze, React będzie czekać na zakończenie przetwarzania zdarzeń przed ponownym wyświetleniem.

  • Tak setBody() w swoim przykładzie po tym, jak próby taktować odpowiedzi, więc on ma tylko jeden krok.

Rozwiązanie

W haku ja bym stworzył procesory, które mają dostęp do data i error zmienne. Biorą oddzwanianie (np. useEffect robi) i powoduje jego zmiennej tylko wtedy, gdy jest świeży. Jak tylko zakończy przetwarzanie, zwróci mu wartość null.

export const useMutationAwait = (url, options) => {
  const [body, setBody] = React.useState({});
  const [data, setData] = React.useState(null);
  const [error, setError] = React.useState(null);
  const [isLoading, setIsLoading] = React.useState(false);

  const handleData = (callback) => {
    if (data){
      callback(data);
      setData(null);
    }
  }

  const handleError = (callback) => {
    if (error){
      callback(error);
      setError(null);
    }
  }
    
  React.useEffect(() => {
    const fetchData = async () => {
      setError(null);
      setIsLoading(true);
      console.log("...fetching");
      try {
        const response = await axiosInstance.post(url, body, options);
        setData(response.status);
      } catch (error) {
        console.error(error.response.data);
        setError(error.response.data);
      }
      setIsLoading(false);
    };
    fetchData();
  }, [body]);

  return [{ data, handleData, isLoading, error, handleError }, setBody];
};

Teraz rejestrujemy obsługi podczas renderowania składnika i za każdym razem data lub error Zmiany:

const [
  { 
    data: mutData, 
    handleData: handleMutData,
    error: mutError,
    handleError: handleMutError
  }, sendPost] = useMutationAwait("/auth/pre-signup");

handleMutData((data) => {
  // If you get here, data is fresh.
});

handleMutError((error) => {
  // If you get here, error is fresh.
});
  
const registerUser = async () => {
    sendPost({
      email,
      password,
    });

Jak i wcześniej, za każdym razem, gdy dane się zmieniają, składnik, który spowodował hak, również będzie aktualizowana. Ale teraz, za każdym razem, gdy jest on aktualizowany, on powoduje handleData lub handleError funkcja, która z kolei uruchamia nasz własny procesor z nowymi świeżymi danymi.

Mam nadzieję, że to pomogło, daj mi znać, jeśli masz jeszcze jakieś problemy.

2021-11-22 20:25:35

Dziękuję, to naprawdę pomogło! I do tego celu czy nie lepiej napisać niektóre cechy wspólne dla GET/POST i przetwarzać dane w zwróconej odpowiedzi z tego decydowali / odrzuconej obietnice?
Adam Martiška

W takiej sytuacji wszystko zależy od dewelopera. Wykorzystaj to, co uważasz za najbardziej przyjazny/łatwy w użyciu, to tylko osobiste preferencje.
Sam McElligott

W innych językach

Ta strona jest w innych językach

Русский
..................................................................................................................
Italiano
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................