Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Native + Redux Form - Use keyboard next button to go to next TextInput field

I'm using Redux Form (RF) in a React Native application. Everything works fine but I can not figure out how to get the refs from the Field input to go to the next input field with Redux Form.

Without RF this solution would work just fine.

Here is my code:

class RenderInput extends Component {
   const { input, nextField, refs,
        meta: { touched, error, warning },
        input: { onChange } } = this.props
   render() {
      return (
         <Input
            returnKeyType = {'next'}
            onChangeText={onChange}
            onBlur={input.onBlur}
            onFocus={input.onFocus}
            onSubmitEditing = {(event) => {
               // refs is undefined
               refs[nextField].focus()
            }}/>
      )
   }
}

class Form extends Component {
   render() {
      return (
         <Field
            name="field1"
            focus
            withRef
            ref='field1'
            nextField = "field2"
            component={RenderInput}/>

         <Field
            name="vendor"
            withRef
            ref="field2"
            nextAction = "field3"
            component={RenderInput}/>
      )
   }
}

I'm passing on the property nextField to the component to determine the next input field when the Next key on the keyboard is clicked but I can not get the refs property inside the RenderInput component.

Any idea how to get the refs property?

like image 354
Thomas Dittmar Avatar asked May 11 '17 14:05

Thomas Dittmar


3 Answers

This solution passes props from the Form component to the RenderInput component and passes a function call back.

Here's the code:

class RenderInput extends Component {
   const { input, refField, onEnter,
        meta: { touched, error, warning },
        input: { onChange } } = this.props
   render() {
      return (
         <TextInput
            ref = {refField}
            returnKeyType = {'next'}
            onChangeText={onChange}
            onBlur={input.onBlur}
            onFocus={input.onFocus}
            onSubmitEditing={onEnter}/>
      )
   }
}

class Form extends Component {
   render() {
      return (
         <Field
            name="field1"
            focus
            withRef
            ref={(componentRef) => this.field1 = componentRef}
            refField="field1"
            component={RenderInput}
            onEnter={() => { 
               this.field2.getRenderedComponent().refs.field2.focus()
            }}/>

         <Field
            name="field2"
            withRef
            ref={(componentRef) => this.field2 = componentRef}
            refField="field2"
            component={RenderInput}/>
      )
   }
} 

So what happened here?

  1. I assign the ref to local scope with ref={(componentRef) => this.field1 = componentRef} as @Ksyqo suggested. Thanks for the hint.

  2. I pass refField="field1" to the RenderInput and assign the value to the input ref property ref = {refField}. This will add the input object to the refs property.

  3. I assigned a onEnter function in the Field

  4. I pass the function to the props of RenderInput and assign it to the onSubmitEditing={onEnter} function. Now we have bind the two functions together. That means if onSubmitEditing gets invoked the onEnter function gets invoked as well

  5. Finally, refer to the local field field2, get the rendered Component and use the refs, which we assigned in the Input field, to set the focus. this.field2.getRenderedComponent().refs.field2.focus()

I don't know if this is the most elegant solution but it works.

like image 189
Thomas Dittmar Avatar answered Sep 19 '22 19:09

Thomas Dittmar


For people who are using Redux Form + React Native Elements, just follow @Thomas Dittmar answer, and add the following prop to the 'FormInput' component: textInputRef={refField}

The newest version of React Native Element has added the focus() method, so you don't have to worry about that.

like image 42
Zach Avatar answered Sep 21 '22 19:09

Zach


withRef is deprecated, use forwardRef instead.

like image 21
7laria Avatar answered Sep 18 '22 19:09

7laria