为什么在 react-hook-form 中使用 useFieldArray() 作为动态表单时,我不能专注于当前字段?



使用react-hook-form 7.14.2我有一个动态表单,我正在使用内置验证。我感觉react-hook-form不能很优雅地处理动态表单,我可能应该停止在这上面折腾,回到一个普通的HTML表单。

在验证发生后,我只想专注于我输入的字段。字段是必需的,但在验证消息显示后,我开始输入,重新渲染发生,焦点丢失在当前字段上…然后跳转回表单中的最后一个字段。这是一个笨拙的,糟糕的用户体验,我似乎只是找不到魔术组合的技巧和技术,让它像一个普通的反应挂钩形式的形式会工作!

形式:

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;

Some ' ainin' to do:

  • 我在那里留下了一堆评论的东西,所以你可以看到我已经尝试过的所有古怪的Stack-O建议-没有一个有效。
  • 我正在加载追加,因为defaultValues不起作用-没有渲染
  • 我只关心w/"url"在
  • 字段上注册/绑定对象的字段。
  • 验证消息行被注释掉,因为我不确定该怎么做w/it

这里有一个关于它如何工作的快速视频。如果我能让字段保持焦点,而不是像这样跳到最下面的字段,我会很高兴的。

https://www.tiktok.com/@zambizzi/视频/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>
);

最新更新