繁体   English   中英

为什么在 react-hook-form 中对动态表单使用 useFieldArray() 时不能关注当前字段?

[英]Why can't I focus on the current field when using useFieldArray() for dynamic form in react-hook-form?

使用 react-hook-form 7.14.2。 我有一个动态表单,并且正在使用内置验证。 我感觉 react-hook-form 不能非常优雅地处理动态 forms ,我可能应该停止对此进行搅动,并退回到普通的 HTML 形式。

在验证发生后,我只想专注于我正在输入的字段。 这些字段是必需的,但是在显示验证消息并且我开始输入之后,会发生重新渲染并且焦点会丢失在当前字段上......它会跳回到表单中的最后一个字段。 这是一个笨拙、糟糕的用户体验,我似乎无法找到技巧和技术的神奇组合来让它像普通的 react-hook-form 表单一样工作!

形式:

import React, { useEffect } from "react";
import { useForm, useFieldArray } from "react-hook-form";
import { Icon } from "@iconify/react";

import socials from "../../enum/social";

const SocialLinksEdit = props => {
    const {
        socialLinks,
        onSave,
        onCancel
    } = props;

    const { control, register, setValue, setFocus, handleSubmit, formState: { errors } } = useForm();

    const { fields, append } = useFieldArray({
        control,
        name: "socialItems"
    });

    useEffect(() => {
        Object.entries(socials).find(([, s]) => append(s));
    }, []);

    const getErrorMessage = i => {
        if (!errors || Object.keys(errors).length === 0) {
            return;
        }
        if (errors.socialItems && errors.socialItems[i]) {
            return errors.socialItems[i].url.message;
        }
        return null;
    };

    const SocialItems = () => {
        const onFocus = field => {
            // setValue(e.target.value);
            setFocus(field);
        };
        const onFocusOut = e => {
            setValue(e.target.value);
        };
        return (
            <>
                {
                    fields.map((field, i) => {
                        let socialData = socialLinks.find(sl => sl.social_service === field.name);
                        console.log(errors);
                        return (
                            <div key={i} className="modal-input-field modal-input-mb">
                                <div className="modal-label-container">
                                    <label className="modal-label">
                                        <span className="modal-label-icon"><Icon icon={field.icon} /></span>
                                        {field.label}
                                    </label>
                                </div>
                                <input
                                    type="text"
                                    // autoFocus={i === 0}
                                    ref={control}
                                    autoFocus
                                    // onFocus={() => onFocus(`socialItems.${i}.url`)}
                                    // onFocusOut={onFocusOut}
                                    {...register(`socialItems.${i}.url`, { required: "URL is required!" })}
                                    defaultValue={socialData?.url}
                                />
                                {errors && <span className="validation">{getErrorMessage(i)}</span>}
                            </div>
                        );
                    })
                }
            </>
        );
    };

    return (
        <div className="modal-container">
            <div>
                <form onSubmit={handleSubmit(onSave)}>
                    <div className="modal-title-container">
                        <div className="modal-title-icon"><Icon icon="bi:megaphone" /></div>
                        <div className="modal-title">Social Links</div>
                    </div>
                    <SocialItems />
                    <div className="modal-buttons">
                        <button type="submit" className="form-button-primary">Save</button>
                        <button type="button" className="form-button-cancel" onClick={e => onCancel(e)}>Cancel</button>
                    </div>
                </form>
            </div>
        </div>
    );
};

export default SocialLinksEdit;

一些'splainin'做:

  • 我在那里留下了一堆评论的东西,这样你就可以看到我已经尝试过的所有古怪的 Stack-O 建议——它们都不起作用。
  • 我在加载时附加,因为 defaultValues 不起作用 - 没有渲染
  • 我只关心在该字段上注册/绑定的 object 的“url”字段
  • 验证消息行被注释掉了,因为我不确定如何处理它

这是有关其行为方式的快速视频。 如果我能让场地保持专注而不是像这样跳到底部场地,我会很开心。

https://www.tiktok.com/@zambizzi/video/7093151720624147755?is_from_webapp=1&sender_device=pc&web_id=7039430208454280710

事实证明,只是将字段直接嵌套在内部,而不是在单独的组件中,以防止重新渲染:

return (
    <div className="modal-container">
        <div>
            <form onSubmit={handleSubmit(onSave)}>
                <div className="modal-title-container">
                    <div className="modal-title-icon"><Icon icon="bi:megaphone" /></div>
                    <div className="modal-title">Social Links</div>
                </div>
                {
                    fields.map((field, i) => {
                        let socialData = socialLinks.find(sl => sl.social_service === field.name);
                        console.log(errors);
                        return (
                            <div key={i} className="modal-input-field modal-input-mb">
                                <div className="modal-label-container">
                                    <label className="modal-label">
                                        <span className="modal-label-icon"><Icon icon={field.icon} /></span>
                                        {field.label}
                                    </label>
                                </div>
                                <div>
                                    <input
                                        type="text"
                                        autoFocus
                                        {...register(`socialItems.${i}.url`, { required: "URL is required!" })}
                                        defaultValue={socialData?.url}
                                    />
                                    {errors && <span className="validation">{getErrorMessage(i)}</span>}
                                </div>
                            </div>
                        );
                    })
                }
                <div className="modal-buttons">
                    <button type="submit" className="form-button-primary">Save</button>
                </div>
            </form>
        </div>
    </div>
);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM