Vejamos como usar ref como prop normalmente!
Com a chegada do React 19, finalmente podemos nos despedir do incômodo forwardRef em muitos casos simples. Uma das mudanças mais sutis — porém poderosas — foi a melhoria no comportamento do ref, que agora pode ser passado como uma prop comum para componentes funcionais.
Essa mudança ajuda a deixar nosso código mais limpo e intuitivo, especialmente em bibliotecas como React Native, onde usamos ref com frequência para acessar elementos como TextInput, ScrollView, FlatList, etc.
🧠 Antes: forwardRef obrigatório
Até o React 18, se quiséssemos que um componente personalizado aceitasse ref, éramos obrigados a envolver o componente com forwardRef. Veja:
// MeuInput.tsx (antes)
import React, { forwardRef } from 'react'
import { TextInput, TextInputProps } from 'react-native'
export const MeuInput = forwardRef<TextInput, TextInputProps>((props, ref) => {
return <TextInput ref={ref} {...props} />
})
No componente pai, usamos o ref normalmente:
// Pai.tsx
import React, { useRef } from 'react'
import { View, Button, TextInput } from 'react-native'
import { MeuInput } from './MeuInput'
export const Pai = () => {
const inputRef = useRef<TextInput>(null)
return (
<View>
<MeuInput ref={inputRef} />
<Button title="Focar" onPress={() => inputRef.current?.focus()} />
</View>
)
}
📌 Problema: você era obrigado a usar forwardRef em MeuInput, mesmo que ele fosse simples.
✅ Agora: ref como uma prop comum
Com o React 19, se o seu componente passar o ref diretamente para um elemento compatível, você não precisa mais usar forwardRef.
Veja como fica o mesmo exemplo com React 19:
// MeuInput.tsx (React 19)
import React from 'react'
import { TextInput, TextInputProps } from 'react-native'
export const MeuInput = (props: TextInputProps & { ref?: React.Ref<TextInput> }) => {
return <TextInput {...props} />
}
E no componente pai, nenhuma mudança:
// Pai.tsx
import React, { useRef } from 'react'
import { View, Button, TextInput } from 'react-native'
import { MeuInput } from './MeuInput'
export const Pai = () => {
const inputRef = useRef<TextInput>(null)
return (
<View>
<MeuInput ref={inputRef} />
<Button title="Focar" onPress={() => inputRef.current?.focus()} />
</View>
)
}
✅ Sem forwardRef!
O React agora entende que se você passar um ref como prop e ele for encaminhado diretamente para um elemento interno (TextInput nesse caso), tudo funciona automaticamente.
🔥 E mais: ref com cleanup (React 19)
Outra melhoria sutil: callbacks de ref agora podem retornar uma função de cleanup, como os efeitos (useEffect):
<TextInput
ref={(node) => {
console.log('Montado', node)
return () => {
console.log('Desmontado', node)
}
}}
/>
⚠️ Limitações
Nem tudo são flores. Essa simplificação só funciona se:
- O
reffor passado diretamente para um elemento nativo ou DOM. - O seu componente não interceptar ou modificar o
refinternamente.
Se você quiser aplicar lógica extra ao ref ou combiná-lo com outro, ainda será necessário usar forwardRef.
📦 Conclusão
O React 19 traz pequenas mudanças que, somadas, deixam o desenvolvimento mais fluido e elegante. Com essa melhoria no uso de ref, conseguimos:
- Eliminar
forwardRefde muitos componentes. - Reduzir boilerplate.
- Ter código mais simples e direto.
🧩 Quando ainda é necessário usar forwardRef
Mesmo com as melhorias do React 19, o forwardRef ainda é necessário em alguns cenários mais avançados. Veja um exemplo real:
❌ Exemplo que não funciona sem forwardRef
import React from 'react'
import { View, Text, ViewProps } from 'react-native'
export const MeuBox = (props: ViewProps & { ref?: React.Ref<View> }) => {
const { style, children, ...rest } = props
return (
<View ref={props.ref} style={[{ padding: 12 }, style]} {...rest}>
<Text>{children}</Text>
</View>
)
}
Nesse caso, o React não garante que o ref será passado corretamente, pois o componente não é “transparente”.
✅ Correto: usando forwardRef
import React, { forwardRef } from 'react'
import { View, Text, ViewProps } from 'react-native'
export const MeuBox = forwardRef<View, ViewProps>(({ style, children, ...rest }, ref) => {
return (
<View ref={ref} style={[{ padding: 12 }, style]} {...rest}>
<Text>{children}</Text>
</View>
)
})
⚠️ Outros casos que ainda exigem forwardRef
| Situação |
forwardRef necessário? |
|---|---|
| Ref é aplicado diretamente a um elemento DOM/Nativo | ❌ Não |
| Ref é interceptado ou modificado internamente | ✅ Sim |
Ref precisa ser armazenado ou combinado com outro (mergeRefs) |
✅ Sim |
Componente precisa expor imperativamente uma API via ref
|
✅ Sim |
Mesmo com as melhorias, o forwardRef ainda é uma ferramenta essencial em componentes mais complexos. Use o novo comportamento quando possível, mas saiba quando ainda é necessário usar o padrão tradicional.
Top comments (0)