1

I'm building an app on react native and I'm trying to set a ref on an input element from the "react-native-elements" library.

I'm getting the following error:

Type 'HTMLInputElement | null' is not assignable to type 'Ref<TextInput> | undefined'.
  Type 'HTMLInputElement' is not assignable to type 'Ref<TextInput> | undefined'.
    Property 'current' is missing in type 'HTMLInputElement' but required in type 'RefObject<TextInput>'.ts(2322)
index.d.ts(89, 18): 'current' is declared here.
index.d.ts(140, 9): The expected type comes from property 'ref' which is declared here on type 'IntrinsicAttributes & TextInputProps & RefAttributes<TextInput> & { containerStyle?: StyleProp<ViewStyle>; ... 15 more ...; renderErrorMessage?: boolean | undefined; } & Partial<...>'

My code is the following:

...
import { useState, useRef } from 'react'
import { Input } from 'react-native-elements'

export default function PublishRecipeScreen({ navigation }: RootTabScreenProps<'Publish a recipe'>) {
  

  const ingredientInput = useRef<null | HTMLInputElement>(null)
  const stepInput = useRef<null | HTMLInputElement>(null)


  return (
    <SafeAreaView>
      <ScrollView contentContainerStyle={styles.container}>

        <Text style={styles.title}>Ingredients:</Text>
        {recipeIngredients ? recipeIngredients.map((item, i) => <p key={i}>{item}</p>) : null}
        
        <Input
          inputContainerStyle={styles.textInput}
          placeholder='Ingredient ...'
          errorStyle={{ color: 'red' }}
          errorMessage={formHasErrors && !recipeIngredients ? 'Please provide the recipe ingredients' : undefined}
          onChangeText={(text: string) => setIngredient(text)}
          multiline = {true}
          ref={ingredientInput.current}
        />

        <TouchableOpacity onPress={() => {
          setRecipeIngredients([... recipeIngredients, ingredient])
          setIngredient('')
        }}>
          <Text>New ingredient</Text>
        </TouchableOpacity>
        
        <Text style={styles.title}>Recipe:</Text>
        {recipeSteps ? recipeSteps.map((item, i) => <p key={i}>{item}</p>) : null}

        <Input
          inputContainerStyle={styles.textInput}
          placeholder='Recipe step ...'
          errorStyle={{ color: 'red' }}
          errorMessage={formHasErrors && !recipeSteps ? 'Please provide the recipe steps' : undefined}
          onChangeText={(text: string) => setStep(text)}
          multiline = {true}
          ref={stepInput}
        />
        
        ...

I looked for the element definition and is as following:

    interface FunctionComponent<P = {}> {
        (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
        propTypes?: WeakValidationMap<P> | undefined;
        contextTypes?: ValidationMap<any> | undefined;
        defaultProps?: Partial<P> | undefined;
        displayName?: string | undefined;
    }

I tried using that as the ref type but didn't work either. What am I supposed to use as the ref type or how could I figure it out?

Full code can be found here: https://github.com/coccagerman/mixr

Thanks!

1 Answer 1

3

Your TextInput refs are not HTMLInputElements, they are TextInputs. Maybe you are used to typing them that way from web React. They're different in React Native.

Instead of

const ingredientInput = useRef<null | HTMLInputElement>(null)
  const stepInput = useRef<null | HTMLInputElement>(null)

Try

const ingredientInput = useRef<null | TextInput>(null)
  const stepInput = useRef<null | TextInput>(null)

In general you can try using the code in the Typescript error message.

Sign up to request clarification or add additional context in comments.

1 Comment

I still screw up using p and div tags instead of text and views, but it's coming along, haha.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.