bamlab/react-native-formik

Using React Hooks & withNextInputAutoFocus together

AsadSaleh opened this issue · 4 comments

Thanks for this awesome lib, it has been fun all the time to use it. I have a question though on how could i use withNextInputAutoFocus and my functional Hooks component. According to your docs, using withNextInputAutoFocus requires us to have a focus method, with a sole purpose to focus on the element.

The problem occurs when I'am using hooks. As we know that in functional component you can't have a method, on the other hand, because you want to use hooks you cannot use class. So I'am stuck in the middle of both. I really hope I can use Hooks and withNextInputAutoFocus together as I really enjoyed working with both.

I tried using useImperativeHandle with forwardRef and this module, but cannot get it to work. What it tries to do is submit the entire form instead of just focusing to the next input. What am I missing?

import React, { useRef, useImperativeHandle, forwardRef} from 'react';
import {
  Item,
  Input,
  Label,
  Icon,
} from 'native-base';
import { TextInput as RNTextInput } from 'react-native';
import { withFormikControl } from 'react-native-formik';
import {MaskService, TextInputMaskOptionProp} from 'react-native-masked-text';

import FormError from './FormError';

const TextInput = (props, ref) => {
  const { error, touched, name, value, setFieldValue, label, last, maskType, maskOptions } = props;

  let inputRef = useRef();
  useImperativeHandle(ref, () => ({
    focus: () => {
      inputRef.current.focus();
    }
  }));

  return (
    <>
      <Item
        floatingLabel
        error={error !== undefined}
        success={touched && error === undefined}
      >
        <Label>{label}</Label>
        <Input
          {...props}
          value={value}
          onChangeText={setFieldValue}
          returnKeyType={last ? 'done' : 'next'}
          ref={inputRef}
        />
        {error ? (<Icon danger name='close-circle' />) : <></>}
        {touched && !error ? (<Icon success name='checkmark-circle' />) : <></>}
      </Item>
      <FormError error={error} />
    </>
  );
};

export default withFormikControl(forwardRef(TextInput));

I'm creating my input in the parent form with:

import {
  Form,
} from 'native-base';
import { Formik } from 'formik';
import {
  handleTextInput,
  withNextInputAutoFocusInput,
  withNextInputAutoFocusForm,
  withInputTypeProps,
} from 'react-native-formik';
...
import {
  TextInput,
} from '../common';
...
const ComposedTextInput = compose(
  handleTextInput,
  withNextInputAutoFocusInput,
  withInputTypeProps,
)(TextInput);
const FormView = withNextInputAutoFocusForm(Form);

@appjitsu You need to move the withNextInputAutoFocusInput HOC to the end:

const ComposedTextInput = compose(
  handleTextInput,
  withInputTypeProps,
  withNextInputAutoFocusInput, // <- here
)(TextInput);
mymy47 commented

This solution worked for me:

import React, { forwardRef } from 'react'
import { TextInput } from 'react-native'
import {
  handleTextInput,
  withInputTypeProps,
  withNextInputAutoFocusInput,
} from 'react-native-formik'
import { compose } from 'recompose'

const CustomTextInput = (props, ref) => {
  return (
    <TextInput {...props} ref={ref}/>
  )
}

export const FormikInput = compose(
  handleTextInput,
  withInputTypeProps,
  withNextInputAutoFocusInput,
)(forwardRef(CustomTextInput))