javascript - handleBlur'ın herhangi bir şey yapmasını durdur


Formik formumda, arama düğmesine tıkladığımda bir öğe listesi (UsersFoundList) render ediliyor. Bu liste formun dışında ve listedeki her öğenin kendi düğmesi var.

Listedeki bu düğmelerden herhangi birine ilk kez tıkladığımda, çalışmıyorlar. Bunun yerine, formumdaki handleBlur tetikleniyor ve çünkü giriş alanı boş, bir hata mesajı giriş alanının altında görünmeye başlıyor. Yani, düğme ilk denemede yapması gerekeni yapmıyor. handleBlur'u bir konsol logu yazarak test ettim.

Bu hata yalnızca formu tekrar göndermeye çalıştığımda görünmeli. Başka bir şeye tıkladığımda değil.

const [showFlatList, setShowFlatList] = useState(false);

    const handleSubmitForm = (
    values: FormValues,
    helpers: FormikHelpers<FormValues>,
  ) => {
    console.log('hello', values.input)
    setShowFlatList(true);
    helpers.resetForm();
  };
  return (
    <View style={styles.container}>
      <View >
          <Formik
            initialValues={initialValues}
            onSubmit={handleSubmitForm}
            validationSchema={addRelationValidationSchema}>
            {({ handleChange, handleBlur, handleSubmit, values }) => (
              <View style={styles.searchFieldContainer}>
                <View style={styles.form}>
                  <FieldInput
                    handleChange={handleChange}
                    handleBlur={handleBlur}
                    value={values.input}
                    fieldType="input"
                    icon="user"
                    placeholderText="E-Mail oder Telefonnummer oder Name"
                  />
                  <ErrorMessage
                    name="input"
                    render={(msg) => <ErrorText errorMessage={msg} />}
                  />
                </View>
                <View style={styles.buttonContainer}>
                  <NewButton buttonText="Suchen" onPress={handleSubmit} />
                </View>
              </View>
            )}
          </Formik>
        </View>
                <View style={styles.listHolder}>
          {showFlatList && (
            <UsersFoundList/>
          )}
        </View>
    </View>
  );

Eğer bir telefonda codesandbox'ı çalıştırırsanız, problemi görebilirsiniz:

https://snack.expo.io/@nhammad/jealous-beef-jerky

handleBlur'un herhangi bir şey yapmasını durdurmam gerekiyor. Listedeki bir butona tıklarsam, handleBlur'u tetiklemek yerine ilk denemede çalışmalı. validateOnBlur=false eklesem bile sorun devam ediyor. Bu durumda, hata mesajı görünmüyor ama buton hala ilk denemede çalışmıyor.

Tıkladığım butonun ayrı bir işlevi var. ve bu buton formun dışında, bu yüzden onBlur içinde yaptığı herhangi bir şeyi yapmak yerine aslında olması gerektiği şeyi yapmalı (sandbox'ta: sadece yazdırıyor).

Cevap #1

onBlur, Formik kullanırken varsayılan davranıştır. Bir alana odaklanmışsanız tetiklenecektir, formun dışında bir şeye tıklasanız da tıklamasanız da.

Ve onBlur, herhangi bir onClick olayından önce tetiklenecektir.

Birkaç geçici çözüm yolu var.

  1. onClick yerine onMouseDown (& onKeyDown) kullanın

Temelde, onMouseDown, onBlur'dan önce çağrılacaktır. İşte burada bir örnek uygulama görebilirsiniz: https://github.com/formium/formik/issues/2062

<a
    href="#back-to-previous"
    onMouseDown={onClick}
    onKeyUp={(e) => {
      e.key === 'Enter' && onClick(e);
    }}
>

onKeyDown erişilebilirlik için vardır ve sadece herhangi bir tuşa değil, basılan tuşun Enter tuşu olup olmadığını kontrol etmelisiniz.

  1. onBlur'u geçersiz kıl ve formik onBlur'u koşullu olarak çağır

Bu kulağa sıradan gelebilir, ama bazı senaryolara uyan olabilir.

Örnek :

onBlur={(e) => {
  const wasLinkClicked = e.relatedTarget && e.relatedTarget.tagName === 'A';
   if (!wasLinkClicked) {
      handleBlur(e);
  }
}}

O kod, bir linke tıklayıp tıklamadığınızı kontrol eder. Sizin durumunuzda farklı bir mantık yazabilirsiniz: "Tıklanan buton formun içinde miydi?".

Cevap #2

FieldInput tanımınızda, her render olduğunda onBlur sırasında fonksiyonu çağırıyorsunuz.

Bunun olmasını önlemek için, React'in yalnızca blur olayında render edeceği bir ok fonksiyonu kullanabilirsiniz

onBlur={(fieldType) => handleBlur(fieldType)}

React.js Belgelerinde daha kapsamlı bir açıklamayı bulabilirsiniz:

https://reactjs.org/docs/faq-functions.html

İlgili makaleler