bamlab / react-native-formik

Set of helpers to make form awesome with React Native and Formik
MIT License
398 stars 50 forks source link

Using React Hooks & withNextInputAutoFocus together #109

Open AsadSaleh opened 5 years ago

AsadSaleh commented 5 years ago

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.

mlabrum commented 5 years ago

Have you tried using https://reactjs.org/docs/hooks-reference.html#useimperativehandle

appjitsu commented 4 years ago

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);
v-honcharenko commented 4 years ago

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

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

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))