bietkul / react-reactive-form

Angular like reactive forms in React.
MIT License
309 stars 32 forks source link

React native - form values are null #59

Closed ghost closed 4 years ago

ghost commented 4 years ago

Describe the bug

Hi, I'm trying to use this library with React Native. I followed the steps in the Basic example section. Also I configure a React state because I need to show or hide password. But when I click in the show/hide button the form values are null, althought in the screen they are showed.

LOG Form values {"password": "hgf", "rememberMe": true, "username": "Gg"} <- Before click show/hide button LOG Form values {"password": null, "rememberMe": false, "username": null} <- After click show/hide button

Am I skipping any steps?

To Reproduce

import React from 'react';
import { Layout, Text, Button, Icon, CheckBox, Input } from '@ui-kitten/components';
import { StyleSheet } from 'react-native';
import I18n from './../../../util/i18n/I18n';
import { FormBuilder, FieldGroup, FieldControl, Validators, FormControl } from 'react-reactive-form';
import Typography from '../../../styles/Typography';
import Global from '../../../styles/Global';

export const Login = ({ navigation }: any) => {

    const [secureTextEntry, setSecureTextEntry] = React.useState(true);

    const form = FormBuilder.group({
        username: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required]),
        rememberMe: new FormControl(false)
    });

    const handleSubmit = (event: any) => {
        event.preventDefault();
        console.log('Form values', form.value);
    }

    const renderSecureTextEntryIcon = (style: any) => (
        <Icon {...style} name={secureTextEntry ? 'eye-off' : 'eye'} />
    );

    const onSecureTextEntryIconPress = () => {
        setSecureTextEntry(!secureTextEntry);
    };

    return (
        <Layout style={{
            ...styles.pageContainer,
            ...Global.container,
            ...Global.h100
        }}>
            <Layout style={styles.fieldGroupContainer}>
                <FieldGroup
                    control={form}
                    strict={false}
                    render={({ get, invalid }) => (
                        <Layout>
                            <FieldControl
                                strict={false}
                                control={form.controls.username}
                                meta={{ label: `${I18n.t('login.form.username')}` }}
                                render={({ handler, touched, hasError, meta }: any) => (
                                    <Layout style={styles.fieldControlContainer} >
                                        <Input
                                            placeholder={`${meta.label}`}
                                            status={touched && hasError('required') ? 'danger' : 'success'}
                                            {...handler()} />
                                        {touched && hasError('required') &&
                                            (<Text status='danger'>
                                                {I18n.t('global.required', { field: meta.label })}
                                            </Text>)
                                        }
                                    </Layout>)} />
                            <FieldControl
                                strict={false}
                                control={form.controls.password}
                                meta={{ label: `${I18n.t('login.form.password')}` }}
                                render={({ handler, touched, hasError, meta }: any) => (
                                    <Layout style={styles.fieldControlContainer} >
                                        <Input
                                            placeholder={`${meta.label}`}
                                            secureTextEntry={secureTextEntry}
                                            icon={renderSecureTextEntryIcon}
                                            onIconPress={onSecureTextEntryIconPress}
                                            status={touched && hasError('required') ? 'danger' : 'success'}
                                            {...handler()} />
                                        {touched && hasError('required') &&
                                            (<Text status='danger'>
                                                {I18n.t('global.required', { field: meta.label })}
                                            </Text>)
                                        }
                                    </Layout>
                                )} />
                            <FieldControl
                                strict={false}
                                control={form.controls.rememberMe}
                                meta={{ label: `${I18n.t('login.form.rememberMe')}` }}
                                render={({ handler, touched, hasError, meta }: any) => (
                                    <CheckBox style={styles.fieldControlContainer}
                                        text={`${meta.label}`}
                                        {...handler('checkbox')}
                                    />
                                )} />
                            <Button onPress={handleSubmit} size='medium' disabled={invalid}>
                                {I18n.t('login.title')}
                            </Button>
                        </Layout>
                    )}
                />
            </Layout>
            <Layout style={{ ...styles.footerContainer }}>
                <Text style={Typography.textCenter}>{I18n.t('login.messages.dontHaveAnAccount')}</Text>
                <Button style={{ marginTop: 5 }} appearance='ghost'>
                    {I18n.t('signUp.title')}
                </Button>
            </Layout>
        </Layout>
    );
}

Expected behavior Screenshots

Desktop (please complete the following information):

Additional context

bietkul commented 4 years ago

@alobaton Define the form-control outside of the React component since you're using hooks and every time you're component re-renders you're initializing the form again. I hope it helps.

ghost commented 4 years ago

@bietkul Man, my fault... I'm still new to react. Thank you very much, it was very helpful! Now I know something about hooks.