TypeScript kullanılarak React Native'de FunctionComponent ile forwardRef nasıl kullanılır

Oct 22 2020

Pek çok dokümana ve örneğe baktım ama yine de forwardRefReact Native'de TypeScript ile işlevsel bir bileşenle nasıl kullanılacağını tam olarak anlayamıyorum . Aşağıda, MyCustomComponentref oluşturarak ebeveynden çağırmaya çalıştığım özel işlevli bir oluşturduğum bir örnek var . Bununla birlikte, ref yanlış tanımlandığından ve nullaçıkça bana fonksiyonun olmadığını söyleyen bir hata mesajı alıyorum. Lütfen forwardRefReact Native'de nasıl doğru şekilde kullanılacağını anlamama yardım edin . Şimdiden teşekkürler!

interface MyCustomComponentProps {
    title: string
}

const MyCustomComponent: React.FunctionComponent<MyCustomComponentProps> = React.forwardRef((props, ref) => {
    const coolAlert = () => {
        Alert.alert('Hey!', 'This was called from MyCustomComponent')
    }
    return (
        <View>
            <Text>{props.title}</Text>
        </View>
    )
})

export default function App () {
    const MyCustomComponentRef = useRef()
    return (
        <SafeAreaView>
            <MyCustomComponent ref={MyCustomComponentRef} title='Hello World' />
            <TouchableOpacity
                onPress={() => {
                    MyCustomComponentRef.coolAlert()
                }}>
                <Text>Click Me</Text>
            </TouchableOpacity>
        </SafeAreaView>
    )
}

Yanıtlar

3 LindaPaiste Oct 22 2020 at 23:27

Ref Yönlendirme

Referanslar gerçekten kafa karıştırıcı olabilir çünkü onları ele almanın birden fazla yolu vardır ve insanlar ref nesnesi ( React.MutableRefObjectveya React.RefObject) ile .currentref nesnesinin özelliğinde depolanan ref değeri arasındaki farkın farkında değillerdir . Bu hatayı, bazı eksik veya yanlış daktilo türleriyle birlikte burada yaptınız.

useRef<T>değerin Tne tür bir değerin depolanacağını söylediği genel bir kancadır . Bir Appşeyi bir coolAlertyöntemle saklamak istediğimizi söylememiz gerekir . Aslında daha sonra ref'imizin değişmez olmasına ihtiyacımız olduğunu göreceğiz, bu yüzden createRef<T>onun yerine kullanacağız .

interface MyRef {
  coolAlert(): void;
}

const MyCustomComponentRef = createRef<MyRef>();

Dediğimiz zaman onPress, biz ref nesnenin geçerli değerini erişmek gerekir. Geneli ekleyerek createRef, typcript bu değerin ya MyRefda olduğunu zaten bilir undefined. coolAlertOpsiyonel zincirleme ?.operatörü ile arayabiliriz .

onPress={() => MyCustomComponentRef.current?.coolAlert()}

Şimdi üzerinde biraz çalışmamız gerekiyor MyCustomComponent. Buna tür atayarak hata yaptınız React.FunctionComponent<MyCustomComponentProps>çünkü bir işlev bileşeni, ihtiyacımız olan ref yönlendirme hakkında bilgiye sahip değil.

function forwardRef<T, P = {}>(Component: RefForwardingComponent<T, P>): ForwardRefExoticComponent<PropsWithoutRef<P> & RefAttributes<T>>;

Tip MyCustomComponentgelen bu karmaşık döndürme türü olmalıdır forwardRef. Ama biz o tip kendimizi atamak gerekmez, sadece jeneriği geçmesi gerekiyor Tve Phiç forwardRefişlev çağrısı. Treferansın Ptürüdür ve sahne tipidir.

const MyCustomComponent = React.forwardRef<MyRef, MyCustomComponentProps>(...

Tamam , tüm daktilo hatalarından kurtulduk ! Yaşasın! Bekle ... Aslında hiçbir şey yapmaz . Bunların hepsi ve hala çalışmıyor. Hakemlerden nefret ederim. Referanslar kötü.

Ref kullanma

Ref MyCustomComponent, iletilen ref'e artık erişimi olan ve onu bir DOM bileşenine ekleyebilen kişiye ilettik. Ancak DOM öğesine eklenmesini istemiyoruz, eklenmesini istiyoruz MyCustomComponent. Ama bunu gerçekten yapamayız.

Varsayılan olarak, örnekleri olmadığı için işlev bileşenlerinde ref özelliğini kullanamazsınız [docs]

useImperativeHandleBir hack çözümü gibi görünen ve hatta dokümanlar "bunu yapma" diyen bir kancayı kullanmalıyız . Evet, hakemlerden nefret ediyorum.

useImperativeHandle, ref kullanılırken üst bileşenlere maruz kalan örnek değerini özelleştirir. Her zaman olduğu gibi, çoğu durumda ref kullanan zorunlu koddan kaçınılmalıdır. useImperativeHandle, forwardRef ile birlikte kullanılmalıdır. [dokümanlar]

Bizim maruz kalmaları coolAlertsayesinde yöntemi useImperativeHandle.

useImperativeHandle(ref , () => ({coolAlert}));

Ve şimdi gerçekten işe yarıyor , nihayet!