Сброс начального состояния useState - PullRequest
0 голосов
/ 28 марта 2019

Чтобы улучшить свои навыки реагирования, я пытался создать многократно используемую форму состояния и средство проверки формы. Мой пользовательский хук FormState инициализирует объект с пустыми строками для значений, которые будут использоваться в качестве начального состояния для моего хука. Я написал функцию clearInputs, которую ожидал сбросить свои входные данные до их начального состояния, но он не обновляется.

Я искал ответ, даже ссылаясь на этот пост переполнения стека: Сброс в исходное состояние с помощью React Hooks . До сих пор нет игры в кости.

// MY FORMSTATE HOOK
import { useState } from 'react';

const FormState = props => {
    let initialState = { ...props };

    const [ inputs, setInputs ] = useState(initialState);

    const [ errors, setErrors ] = useState(initialState);

    const handleInput = e =>
        setInputs({
            ...inputs,
            [e.target.name]: e.target.value
        });

    const handleError = errs => setErrors({ ...errors, ...errs });

    const resetForm = () => {
        setInputs({ ...initialState });
        setErrors({ ...initialState });
    };

    const clearInputs = () => {
        console.log('SUPPOSED TO CLEAR', initialState)
        console.log('MY INPUTS', inputs)

        setInputs({ ...initialState });

        console.log('AFTER THE SETTING', inputs)
    };

    return [ inputs, handleInput, errors, handleError, resetForm, clearInputs ];
};

export default FormState;
// REGISTER FORM
import React, { useEffect } from 'react';
import { connect } from 'react-redux';

import FormState from './formState';
import Field from './field';

import { registerUser } from '../../actions/users';

import './forms.css';

const RegisterForm = props => {
    const isLoggedIn = localStorage.getItem('user');

    useEffect(
        () => {
            if (isLoggedIn) {
                const parsedUser = JSON.parse(isLoggedIn);
                props.history.push(`/profile/${parsedUser.pk}`);
            }
        },
        [ isLoggedIn ]
    );

    const initialInputs = {
        username: '',
        password1: '',
        password2: '',
        first_name: '',
        last_name: ''
    };

    const [ inputs, handleInput, errors, handleErrors, resetForm, clearInputs ] = FormState(initialInputs);

    const handleSubmit = e => {
        e.preventDefault();

        const validForm = validate(inputs, handleErrors);

        if (validForm) {
            props.registerUser(inputs);
            resetForm();
        }
        else {
            clearInputs();
        }
    };

    return (
        <div className='form-wrap'>
            <h1>Register Here</h1>
            <form className='form' onSubmit={handleSubmit}>
                <Field
                    label='Username'
                    fieldname='username'
                    value={inputs.username}
                    placeholder='Enter Your Username'
                    fielderror={errors.username}
                    handleInput={handleInput}
                    classNames='form-section'
                />
                <Field
                    label='Password'
                    fieldname='password1'
                    value={inputs.password1}
                    placeholder='Enter Your Password'
                    fielderror={errors.password1}
                    handleInput={handleInput}
                    classNames='form-section'
                />
                <Field
                    label='Confirm Password'
                    fieldname='password2'
                    value={inputs.password2}
                    placeholder='Confirm Your Password'
                    fielderror={errors.password2}
                    handleInput={handleInput}
                    classNames='form-section'
                />
                <Field
                    label='First Name'
                    fieldname='first_name'
                    value={inputs.first_name}
                    placeholder='Enter Your First Name'
                    fielderror={errors.first_name}
                    handleInput={handleInput}
                    classNames='form-section'
                />
                <Field
                    label='Last Name'
                    fieldname='last_name'
                    value={inputs.last_name}
                    placeholder='Enter Your Last Name'
                    fielderror={errors.last_name}
                    handleInput={handleInput}
                    classNames='form-section'
                />
                <button type='submit' className='submit-button'>
                    Submit
                </button>
            </form>
        </div>
    );
};

const validate = (inputs, handleErrors) => {
    let errs = {};
    const { username, password1, password2, first_name, last_name } = inputs;
    if (!username) {
        errs.username = 'Username is missing';
    }
    if (!password1) {
        errs.password1 = 'Password is missing';
    }
    if (!password2) {
        errs.password2 = 'Confirm password is missing';
    }
    if (!first_name) {
        errs.first_name = 'First name is required';
    }
    if (!last_name) {
        errs.last_name = 'Last name is required';
    }
    if (username.length < 6) {
        errs.username = 'Username is too short';
    }
    if (password1.length < 8) {
        errs.password1 = 'Password is too short';
    }
    if (password1 !== password2) {
        errs.password1 = 'Passwords must match';
        errs.password2 = 'Passwords must match';
    }

    if (Object.keys(errs).length) {
        handleErrors(errs);
        return false;
    }
    else {
        return true;
    }
};

const mapStateToProps = state => {
    return {
        loggedInUser: state.users.loggedInUser,
        registerPending: state.users.registerPending,
        registerError: state.users.registerError
    };
};

const mapDispatchToProps = dispatch => {
    return {
        registerUser: newUser => {
            dispatch(registerUser(newUser));
        }
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(RegisterForm);

Когда сработает clearInputs, он должен сбросить входы в исходное состояние. Вместо этого ничего не происходит. Любая помощь очень ценится.

EDIT: Позвольте мне уточнить. Каждому полю в моей форме передается значение из входных данных (имя пользователя, пароль1 и т. Д.). Когда вызывается clearInputs, он очищает входы в ловушке, но не очищает значения в поле.

Ответы [ 2 ]

0 голосов
/ 28 марта 2019

О том, почему вы входите в систему, неправильно, нужно понимать это: каждый раз, когда вызывается ваш хук (в основном при каждом рендере формы), создается новая функция clearInputs, которая имеет свою собственную версию inputs. Таким образом, в самой функции clearInputs inputs не может измениться, потому что они находятся сверху в области видимости, useState.

Если вы хотите заметить изменения между 2 вызовами вашего хука, вы можете зарегистрировать inputs непосредственно перед возвратом [input, ...].

Опять же, в вашем хуке вы не вызываете setInputs, вы определяете функцию clearInputs, которая будет вызывать изменение состояния, которая будет повторно визуализировать ваш компонент, который снова будет использовать ваш хук, ваш хук прочитает новое значение inputs и создаст новую функцию clearInputs.

0 голосов
/ 28 марта 2019

Ваша clearInputs функция работает как задумано. Функция setInputs, возвращаемая useState, является асинхронной, поэтому в журнале консоли «ПОСЛЕ НАСТРОЙКИ» отображается значение inputs до его обновления.

Здесь показано базовое использование вашего пользовательского крючка .. https://codesandbox.io/s/jznpk7w85w

Кстати, вы должны префикс вашего имени пользовательского крючка с use .. https://reactjs.org/docs/hooks-custom.html#extracting-a-custom-hook

...