重置使用状态的初始状态



为了提高我的 React 技能,我一直在尝试构建一个可重用的表单状态钩子和表单验证器。我的自定义钩子 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 被触发时,它应该将输入重置为初始状态。相反,什么都没有发生。任何帮助真的非常感谢。

编辑:让我进一步澄清。表单中的每个字段都从输入(用户名、密码 1 等(传递一个值。当调用 clearInputs 时,它会清除钩子中的输入,但不会清除字段中的值。

您的clearInputs函数正在按预期工作。useState返回的setInputs函数是异步的,导致"设置后"控制台日志在更新之前显示inputs的值。

自定义钩子的基本用法在这里显示有效.. https://codesandbox.io/s/jznpk7w85w

顺便说一句,您应该在自定义钩子名称前面加上 use.. https://reactjs.org/docs/hooks-custom.html#extracting-a-custom-hook

关于为什么你登录不正确,必须明白这一点:每次调用你的钩子时(基本上在每个表单渲染上(,都会创建一个新的 clearInputs 函数,它有自己的 inputs 版本。因此,在clearInputs函数本身中,inputs不能更改,因为它们来自范围的更高位置,即useState。

如果你想注意到钩子的 2 次调用之间的变化,你可以在返回 [inputs, ...] 之前记录inputs

同样,在你的钩子中,你不是在调用setInputs,你正在定义一个clearInputs函数,它将触发状态更改,这将重新渲染你的组件,它将再次使用你的钩子,你的钩子将读取inputs的新值,并创建一个新的clearInputs函数。

相关内容

  • 没有找到相关文章

最新更新