React özel getirme kancası bir adım geride kaldı

0

Soru

Hem get hem de post verileri için özel getirme kancamı oluşturuyorum. Özel getirme kancaları oluşturmak için resmi React dokümanlarını takip ediyordum, ancak kanca döndürülmüş durum değişkenlerim USESTATE eşzamansız davranışı nedeniyle bir adım geride kalıyor gibi görünüyor. İşte benim özel kullanımımutasyon kancası

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];
};

Ve bunu bileşenimde şu şekilde kullanıyorum (basitleştirilmiş) - kullanıcı kayıt düğmesine bastığında, gönderimin başarılı olup olmadığına hemen karar verebilmek ve buna göre kullanıcıyı başka bir ekrana yönlendirmek veya getirme hatası görüntülemek istiyorum.

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)

Başarmaya çalıştığım bu yaklaşım doğru mu? Temel olarak veri toplama ve veri mutasyonu için bazı genel işlevler oluşturmak istiyorum ve kancaların yol olabileceğini düşündüm.

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

Yaklaşımınız yanlış değil, ancak paylaştığınız kod eksik veya belki modası geçmiş mi? Arama sendPost özel kancanızın içindeki bazı durumları güncellemeniz yeterlidir, ancak onu çağırmanın bir söz vereceğini varsayarsak (POST isteğiniz), yalnızca async-await kullanmalı ve bir try-catch ifadesiyle sarmalısınız.

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
  }
}

Bazı öneriler, özel kancanızı uyguladığınızdan, yalnızca getirme verilerini getiren ve yalnızca istekleri gönderen (POST) başka bir tane uygulayabilirsiniz. Bunu yaparken daha fazla özgürlüğe sahip olursunuz, çünkü bazı sayfalar yalnızca get'e sahip olurken diğerleri POST veya PUT olacaktır. Temel olarak bir kanca uygularken, bir çözüme çok özel hale getirmeyi deneyin.

2021-11-22 20:22:36

Evet, bu yaklaşımı denedim ama tüm değişkenlere sahip olmak istedim { data, isLoading, error, [ve belki mutasyon fonksiyonu?] = Kanca çağrısında döndürülen useMutation(bitiş noktası, gövde).
Adam Martiška
0

Karşılaştığınız sorunun kökü bu olduğundan, durum güncellemelerinin eşzamansız doğasından bahsetmekte kesinlikle haklısınız.

Olan şu şekildedir:

  • Kullanarak durumu güncelleştiriyorsunuz sendPost bir işlevin içinde.
  • React durum güncellemeleri işlev kapsamlıdır. Bu, React'in her şeyi çalıştırdığı anlamına gelir setState() belirli bir işlevde bulduğu çağrıları ancak işlevin çalışması bittikten sonra çağırır. Bu sorudan bir alıntı:

React toplu işlemleri, olay işleyicilerinde ve yaşam döngüsü yöntemlerinde oluşan güncelleştirmeleri belirtir. Bu nedenle, bir işleyicide durumu birden çok kez güncelleştirirseniz React, yeniden oluşturmadan önce olay işlemenin bitmesini bekler.

  • Böyle setBody() örneğinizde, yanıtı işlemeye çalıştıktan sonra çalışıyor, bu yüzden bir adım geride kalıyor.

Çözüm

Kancada, aşağıdakilere erişimi olan işleyiciler oluşturacağım data ve error değişkenler. Bir geri arama alırlar (örneğin useEffect yapar) ve yalnızca taze ise değişkenle çağırır. İşlem tamamlandıktan sonra null olarak ayarlar.

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];
};

Şimdi, bileşen oluşturulduğunda ve her seferinde işleyicileri kaydediyoruz data veya error değişimler:

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,
    });

Daha önce olduğu gibi, veriler her değiştiğinde kanca adı verilen bileşen de güncellenecektir. Ama şimdi, her güncellediğinde handleData veya handleError özel işleyicimizi yeni yeni verilerle çalıştıran işlev.

Umarım bu yardımcı olmuştur, hala sorun yaşıyorsanız bana bildirin.

2021-11-22 20:25:35

Teşekkür ederim bu gerçekten yardımcı oldu! Ve bu amaçla, GET / POST için bazı genel işlevler yazmak ve bu çözümlenmiş / reddedilen sözün döndürülen yanıtındaki verileri işlemek daha iyi değil mi?
Adam Martiška

Böyle bir durumda, her şey geliştiriciye bağlıdır. Hangisini en rahat/kullanımı en kolay bulursanız kullanın, bu sadece kişisel tercihtir.
Sam McElligott

Diğer dillerde

Bu sayfa diğer dillerde

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