-
Notifications
You must be signed in to change notification settings - Fork 10
Description
When using MaskedTextInput in a form controlled by react-hook-form, the input becomes noticeably slow and laggy when multiple instances (e.g., 15) are rendered on the same screen. Some characters are even skipped when typing fast.
This issue does not occur when using MaskedTextInput as an uncontrolled component or controlled via local useState. This suggests the problem might be related to how the component interacts with react-hook-form and React re-renders.
Possibly related to: #82
export const FormMaskedField = ({ name }: { name: string }) => {
const { control } = useFormContext();
const { field } = useController({
name,
control,
});
return (
<MaskedTextInput
onChangeText={field.onChange}
ref={field.ref}
value={field.value}
mask="[__________________________________________________________________]"
style={{
borderRadius: 12,
borderWidth: 1,
borderColor: '#000',
backgroundColor: '#fff',
color: '#000',
padding: 8,
}}
/>
);
};
export const TestForm = () => {
const methods = useForm();
const { watch } = methods;
const values = watch();
return (
<FormProvider {...methods}>
<View style={{ gap: 8 }}>
{[...Array(15)].map((_, index) => (
<View key={index}>
<FormMaskedField name={'test' + index} />
<Text>
testValue{index} - {values['test' + index]}
</Text>
</View>
))}
</View>
</FormProvider>
);
};Typing becomes laggy and unresponsive when many masked inputs are controlled via react-hook-form.
2025-04-07.18.07.13.mov
When switching to a version that uses local state (without react-hook-form), performance is fine:
export const ControlledMaskedField = ({ onChangeText, value }: { value: string; onChangeText: (value: string) => void }) => {
return (
<MaskedTextInput
value={value}
onChangeText={onChangeText}
mask="[__________________________________________________________________]"
style={{
borderRadius: 12,
borderWidth: 1,
borderColor: '#000',
backgroundColor: '#fff',
color: '#000',
padding: 8,
}}
/>
);
};
export const TestStateForm = () => {
const [values, setValues] = useState<Record<string, string>>({});
return (
<View style={{ gap: 8 }}>
{[...Array(15)].map((_, index) => (
<View key={index}>
<ControlledMaskedField
value={values['test' + index] || ''}
onChangeText={val => setValues(prev => ({ ...prev, ['test' + index]: val }))}
/>
<Text>
testValue{index} - {values['test' + index]}
</Text>
</View>
))}
</View>
);
};Expected behavior
Input should remain smooth and responsive even with many MaskedTextInput components using react-hook-form.
- Desktop OS: [MacOS 15.2]
- Android Device: [Samsung S22] API v34 / Android14
- RN version: 0.78
- RN architecture: [old]
- Library version: [1.3.5]