javascriptreactjsreact-nativerefsreact-forwardref

How can i focus on textfield in child file on click of an icon which is in parent file in react native?


What I am trying to achieve is focusing on TextInput present in child component when clicked on an icon present in parent file. I have tried using refs and forward refs but that means i have to wrap the component in forwardref which i am trying to avoid.

 const InputText = React.forwardRef((props, ref) => (
 <input ref={ref} {...props} />
  ));

My child file looks like this:

export const TextField = ({
    label,
    placeholder = "",
     id = "",
  isSecure = false,
   disabled = false,
   handleBlur,
   handleChange,
  value,
   ...props
   }: IProps): React.ReactElement => {
    const { labelStyle, fieldStyle, status=false, search=false,inputStyle, errorStyle } = 
        props;


   //some statements


  <View style={styles.elementsContainer}>
    <TextInput                                   //I want to focus on this
      .......
       .
       .
      onChangeText={handleChange(props.name)}
      onBlur={handleBlur(props.name)}
    />
</View>
);
};
export default TextField;

Below is my parent file where I have an icon and on click of it I trying this textfield to be focused.

return (
<Formik
  initialValues={initialValues}
  onSubmit={(values, { setSubmitting }) => {
    setSubmitting(false);
  }}
>
  {(formikProps: FormikProps<{ searchText: string }>) => (
    <View style={status?styles.highlight:[styles.container,textFieldDimensions]}>
      <TouchableOpacity onPress={addressFocus}>             //This is the icon on click of it i am trying textfield child component to be focused.
         <Icon testID="home" name={IconNames.home} />         
     </TouchableOpacity>
     <View style={styles.textfieldContainer}>
    <TextField                                              //CHild component
      handleChange={formikProps.handleChange}
      status={status}
      handleBlur={() => searchFunction(formikProps.values.searchText)}
      value={formikProps.values.searchText}
      name="searchText"
      placeholder={placeholder}
      search={search}
      label="Search :"
      id="searchText"
      fieldStyle={[styles.field,fieldStyle]}
      inputStyle={styles.input}
      labelStyle={[styles.label, labelStyle]}
    />
    </View>
    </View>
  )}
</Formik>

);


Solution

  • So after brainstorming i come to a simple approach which works for me as of now. But i am not crystal clear from ref part how its working.

    so what i did is in parent file where i am passing props in child component like this:

       const toggle=()=>{
        setToggler(!toggler)                     This function changes state value which is boolean type from false to true and vice versa.
            }
    <TouchableOpacity onPress={toggle}>           //toggle function called on onPress
             <Icon testID="home" name={IconNames.home} />
         </TouchableOpacity>
     <TextField
          toggler={toggler}                       //Now I am passing state toggler into child component, change of this state will re render the component
          handleChange={formikProps.handleChange}
          status={status}
          handleBlur={() => searchFunction(formikProps.values.searchText)}
          value={formikProps.values.searchText}
          name="searchText"
          placeholder={placeholder}
          search={search}
          label="Search :"
          id="searchText"
          fieldStyle={[styles.field,fieldStyle]}
          inputStyle={styles.input}
          labelStyle={[styles.label, labelStyle]}
        />
    

    Now how i am handling refs in child component is that it focus on textinput on click of button.

    All this is happening in functional component, for simplicity react rules has not been taken into account only relevant pieces of code is shown

     const inputRef = useRef<TextInput>(null);
     const onClickFocus = () => {
         {props.toggler && inputRef.current?.focus();}  //If toggler changes to true then this function will execute and perform inputRef.current?.focus();
       }
      onClickFocus()  //Function is called here and later inputRef is utilized in textinput as ref={inputRef}
     <TextInput
          ref={inputRef}
          placeholder={placeholder}
          secureTextEntry={isSecure}
          style={search?  fieldStyle:[styles.inputBox, inputStyle]}
          editable={!disabled}
          value={value}
          {...field}
          onChangeText={handleChange(props.name)}
          onBlur={handleBlur(props.name)}
        />