React18+ Ant5+ Login 表单 API 自定义 rules 回调

上网查了查,目前没看到有人这样写,这个是我自己摸出来的方式,也是最简易的代码:

const login = () => {
    const { t, i18n } = useI18n();
    const [isSubmiting, setSubmit] = useState(false);
    const [form] = Form.useForm();
    const [rules, setRules] = useState({});
    const { showNotification } = useNotification();
    const navigate = useNavigate();
    const [cookies, setCookie] = useCookies();

    useEffect(() => {
        const fields = form.getFieldsError();
        let formFields = [];
        for (const key in fields) {
            formFields.push({
                name: fields[key]['name'][0],
                errors: [],
            });
        }
        if (Object.entries(rules).length > 0) {
            for (let key in formFields) {
                Object.entries(rules).forEach(([k, v]) => {
                    if (k === formFields[key].name) {
                        if (v) {
                            formFields[key].errors = [t(v)];
                        }
                        return;
                    }
                });
            }
        }
        if (formFields.length > 0) {
            form.setFields(formFields);
        }
    }, [rules]);

    const handleSubmit = async (e) => {
        setSubmit(true);
        const fieldValues = form.getFieldsValue();
        const response = await general.useFetch('/auth/member', fieldValues);
        if (response && response.code === 200) {
            const msg = t('login.success');
            showNotification({
                type: 'success',
                msg: msg,
            });
            const maxAge = 24 * 60 * 60; // 1 day
            setCookie('authMember', JSON.stringify(response.auth), {
                path: '/',
                maxAge: maxAge.toString(),
            });
            setSubmit(false);
            navigate('../home');
        } else {
            const msg = 'login.error';
            showNotification({
                type: 'error',
                msg: msg,
            });
            setSubmit(false);

            const _formRules = {};
            if (response && response?.errors?.length > 0) {
                response.errors.forEach((el) => {
                    _formRules[el.field] = el.message;
                });
            }
            setRules(_formRules);
        });
    };
    return (
        <Form layout="vertical" form={form} autoComplete="off">
            {!cookies?.authMember && (
                <Card title={t(siteTitle)} className="text-center w-[360px]">
                    <Form.Item
                        name="username"
                    >
                        <Input
                            placeholder={t('login.username')}
                            prefix={<UserOutlined className="text-gray-400" />}
                        />
                    </Form.Item>
                    <Form.Item
                        name="password"
                    >
                        <Input.Password
                            placeholder={t('login.password')}
                            prefix={<LockOutlined className="text-gray-400" />}
                        />
                    </Form.Item>
                    <Form.Item>
                        <Button
                            type="primary"
                            htmlType="submit"
                            block
                            disabled={isSubmiting}
                            onClick={handleSubmit}
                        >
                            {t('login.button')}
                        </Button>
                    </Form.Item>
                </Card>
            )}
        </Form>
    );
};
export default memo(login);
本作品采用《CC 协议》,转载必须注明作者和本文链接
全栈程序员(Blockchain, Web3, Nuxt3+, vue3+, React18+, PHP, MySQL, HTML, CSS, JavaScrIpt/JQuery)
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!