ui icon indicating copy to clipboard operation
ui copied to clipboard

TextInput ref methods are broken

Open patrick-michelberger opened this issue 8 years ago • 14 comments

I try to call the focus() method on a TextInput ref. Such as

<TextInput ref="emailInput" onSubmitEditing={() => this.focusNextField('passwordInput')}/>
<TextInput ref="passwordInput"/>

// component method
focusNextField = (nextField) => {
  this.refs[nextField].focus();
};

However I get the following Error Message: _this.refs[nextField].focus is not a function

The Reference Type seems to be different compared to the React Native core and doesn't offer methods such as focus()

patrick-michelberger avatar Sep 26 '16 17:09 patrick-michelberger

Hi Partric, this obviously is a bug/missing functionality. We're putting it in our roadmap for one of the next releases.

dculjak avatar Sep 28 '16 05:09 dculjak

Is there any temporary solution?

lijy91 avatar Mar 30 '17 03:03 lijy91

Yes, if you copy the TextInput from this library (https://github.com/shoutem/ui/blob/develop/components/TextInput.js), add a ref at line 22, like so:

<RNTextInput
  {...props}
  style={style}
  placeholderTextColor={props.style.placeholderTextColor}
  selectionColor={props.style.selectionColor}
  ref={(input) => this.props.inputRef(input)}
/>

Then, using that textinput, you can use the inputRef prop as you would a normal ref, like this:

<TextInput inputRef={(input) => { this.textInput = input }} />

The input ref is now available via this.textInput

JulianKingman avatar Mar 31 '17 14:03 JulianKingman

I'm trying out the temporary solution above, and I can't get it to work. I get the following error message: _this2.props.inputRef is not a function.

neegool avatar Apr 27 '17 09:04 neegool

Okay, I found out that by making my own copy of TextInput , and adding a ref="textInput" prop to it, I was able to access the TextInput via this.refs[nextField].wrappedInstance.wrappedInstance.refs.textInput. This will work for me, for now. :)

neegool avatar Apr 27 '17 09:04 neegool

It sounds like you used a string based ref, its recommended to use a callback ref instead.

JulianKingman avatar Apr 27 '17 13:04 JulianKingman

Hi, any progress on this bug? I'm trying to set focus on my next textInput but cannot make it work. thanks

steven-tib avatar Jun 08 '17 08:06 steven-tib

For anyone ending up here struggling with focussing the next TextInput: https://stackoverflow.com/a/45253129/3749432

jenskuhrjorgensen avatar Jan 31 '18 12:01 jenskuhrjorgensen

This issue is still there. Kindly help us. Because this function is very basic.

andyngdz avatar Feb 14 '18 16:02 andyngdz

Workaround is to use connectStyle:

import { connectStyle } from '@shoutem/theme';
import {TextInput as RNTextInput} from 'react-native';

const TextInput = connectStyle('shoutem.ui.TextInput')((p) => (
  <RNTextInput {...p} ref={(a) => p.getRef(a)} />
));

pindamonhangaba avatar Oct 31 '18 17:10 pindamonhangaba

fixed in #471

danalloway avatar Mar 06 '20 17:03 danalloway

Ok, descobri que fazendo minha própria cópia do TextInput e adicionando um ref="textInput"prop a ele, consegui acessar o TextInput via this.refs[nextField].wrappedInstance.wrappedInstance.refs.textInput. Isso vai funcionar para mim, por enquanto. :)

can you help me by showing what you did in your code?

LouisGusta avatar Jan 29 '21 15:01 LouisGusta

Yes, if you copy the TextInput from this library (https://github.com/shoutem/ui/blob/develop/components/TextInput.js), add a ref at line 22, like so:

<RNTextInput
  {...props}
  style={style}
  placeholderTextColor={props.style.placeholderTextColor}
  selectionColor={props.style.selectionColor}
  ref={(input) => this.props.inputRef(input)}
/>

Then, using that textinput, you can use the inputRef prop as you would a normal ref, like this:

<TextInput inputRef={(input) => { this.textInput = input }} />

The input ref is now available via this.textInput

This solution resolve if I own two input component, but where try move to the next input (the third input in screen) , does not work , can you help me?

LouisGusta avatar Jan 29 '21 16:01 LouisGusta

Check out this solution: https://stackoverflow.com/a/77693296/15526921

If you've wrapped a React Native TextInput within a new component and you find that the ref is not working as expected to move to the next input when submitted, there are a few potential reasons and solutions you can explore:

  1. Passing the ref properly:

Ensure that you are correctly passing the ref from the parent component to the wrapped TextInput component. If you are using functional components, you can use the useImperativeHandle hook to expose specific methods or properties of the child component.

  1. Using forwardRef:

Ensure that you are using the forwardRef function when creating your custom component. This is necessary to forward the ref from the parent component to the child component.

  1. Handling focus in the parent component:

If the ref is properly passed, ensure that you are using the focus() method on the next TextInput component in the parent component's handleSubmit function.

//ParentComponent.js
import React, { useRef } from 'react';
import CustomInput from './CustomInput';

const ParentComponent = () => {
   const inputRef1 = useRef(null);
   const inputRef2 = useRef(null);

  const handleSubmit = () => {
    // Do something with the input value
    inputRef2.current.focus();
  };

  return (
    <CustomInput ref={inputRef1} onSubmit={handleSubmit} />
  );
};

// CustomInput.js
import React, { forwardRef } from 'react';
import { TextInput, Button } from 'react-native';

const CustomInput = forwardRef(({ onSubmit }, ref) => {
  return (
    <>
      <TextInput ref={ref} /* other props */ />
      <Button title="Submit" onPress={onSubmit} />
    </>
  );
});

export default CustomInput;

Generated by ChatGPT 3.5 and worked for me after trying several solutions

alieldab3 avatar Dec 20 '23 17:12 alieldab3