React-hook-form 을 다루던 중 useFieldArray 에서 append 될 경우 focus되면 좋을 것 같아서 알아보던 중
MUI를 사용할 경우 따로 설정을 해줘야 한다는 깃헙 이슈를 발견했다.
https://github.com/react-hook-form/react-hook-form/issues/5947
우선 focus를 적용하고 싶은 컴포넌트
...
const SubSkillForm = ({ control, className }: Props) => {
const {
fields: subSkills,
append,
remove,
} = useFieldArray({
control,
name: 'skills.sub',
})
return (
<section className="flex flex-col">
<p className={className}>Sub, 부기술</p>
{subSkills.map((subSkill, index) => {
return (
<div key={subSkill.id} className="flex">
<MuiTextField<TForm>
className="flex-grow"
... 생략
onKeyDown={(e) => {
console.log(e)
if (e.key === 'Enter') {
e.preventDefault()
// 아래처럼 append focusName에 해당하는 input을 focus 한다
append({ name: '', priority: 0 }, { focusName: `skills.sub.${subSkills.length}.name` })
}
}}
/>
<button
type="button"
onClick={() => {
if (subSkills.length === 1) return alert('1개 이상')
remove(index)
}}
>
삭제
</button>
</div>
)
})}
</section>
)
}
export default SubSkillForm
append 두번째 인자로 focusOptions을 옵셔널하게 받는다
여기까지만 작성하면 자동 focus가 안될텐데 아래방법을 따라하면 해결
const MuiTextField = <T extends FieldValues>({
name,
rules,
control,
...
className,
...props
}: TProps<T>) => {
const {
field: { value, onChange, ...field },
fieldState: { error },
} = useController({
name,
rules,
control,
})
return (
<TextField
className={className}
value={value}
...중간생략
{...props}
{...field}
/>
)
}
MUI 타입파일을 까본 결과 inputRef으로 입력하라고 타입지정이 되어있었다.
그런데 저는 field를 스프레드연산자도 그대로 때려넣었더니
ref={ref}
의 형태로 들어가서 제대로 추적이 안되고 있었습니다
MUI에서 요구하는대로 아래처럼 inputRef={ref}
형태로 넣어주면 잘 작동!!
const {
field: { value, onChange, ref, ...field },
fieldState: { error },
} = useController({
name,
rules,
control,
})
return (
<TextField
className={className}
inputRef={ref}
... 생략