react-native-formik
react-native-formik copied to clipboard
withNextInputAutoFocus does not work with nested components
Description
When using self-closing-tag components to generate text fields in a form, the withNextInputAutoFocusForm
does not register the generated textInputs and the expected behaviour does not work : pressing "OK" with a textInput focused submits the entire form.
Steps to reproduce / example
const Form = withNextInputAutoFocusForm(View);
export class ReportForm extends PureComponent<PropsType, StateType> {
renderForm = ({ values, handleSubmit }: { values: any, handleSubmit: Function }) => {
return (
<Form>
<AircraftInformationSection />
</Form>
);
};
render() {
return (
<Formik
// ...
render={this.renderForm}
/>
);
}
}
export class AircraftInformationSection extends PureComponent<PropsType> {
render() {
return (
<View>
<TextInput
name="aircraftInformationSectionType"
// ...
/>
</View>
);
}
}
In this case, getInputs does not see any children in the props of <AircraftInformationSection />
Ideas of technical solution
Create a Provider/Consumer system with textFields subscribing to the form. Add a prop to the form to specify the order of the fields to be focused.
Hi @Gguigre, thanks for reporting!
In getInputs, withNextInputAutoFocusForm
traverses the hierarchy of children of the wrapped component to find inputs.
In your case, only one child is found, which is AircraftInformationSection
, but not an input of course, and AircraftInformationSection
itself does not have any children.
Would it be possible in your case to use withNextInputAutoFocusForm
directly on AircraftInformationSection
?
Hi @Almouro,
unfortunately, the <AircraftInformationSection />
component is not the only one inside the <Form>
and they're other components that generate fields too.
Actually, the renderForm method is more like
renderForm = ({ values, handleSubmit }: { values: any, handleSubmit: Function }) => {
return (
<Form>
<AircraftInformationSection />
<FlightInformationSection />
<EngineInformationSection />
</Form>
);
};
So if I create one <Form />
for each section, the next
won't handle passing between the different sections :(
@Gguigre I believe you should also add that AircraftInformationSection
has several inputs as children, not only one.
Recently merge doesn't fix the issue. The thing is that getInputs
recursive function doesn't get into components without children, so... if you have something like that:
const Address = () => {
return <Box>
<Input name={'address_line_1'}
<Input name={'address_line_2'}
</Box>
}
const RegistrationForm = () => {
<Form>
<Box>
<Input name={'a'} />
<Input name={'b'} />
<Input name={'c'} />
<Input name={'d'} />
</Box>
<Address />
</Form>
}
where Form
is hoc composed with withNextInputAutoFocus
it doesn't not get into Address
component as it does not conform to this part
const getInputs = children =>
//...
if (child && child.props && child.props.children) { // <- well, this
//...
}
//...
}, []);
I'm trying to get the solution for that. I will leave PR for you @Almouro if I have any 🤷♂️
EDIT ok, I've found solution for that one. You can nest Forms, so basically this one below fixes the issue:
const Address = () => {
return <Form>
<Input name={'address_line_1'}
<Input name={'address_line_2'}
</Form>
}
const App = () => {
<Form>
//...
<Address />
//...
</Form>
}