티스토리 뷰

:: 리렌더링을 줄이기 위해 use-hook-form을 사용하는데,

:: 비밀번호 확인(보이기/숨기기), 포커싱 등을 보면 상태를 사용하거나 난감해하는 문제를 맞이한다..내 이야기.

 

1. useImperativeHandle

useImperativeHandle(ref, createHandle, dependencies?)

:: 자식 컴포넌트에서 부모 컴포넌트로 특정 인스턴스 값을 전달할 때 사용

:: 주로, ref를 통해 자식 컴포넌트의 내부 메서드나 속성을 부모 컴포넌트에서 사용할 수 있도록 할 때 사용

:: 즉, 자식의 인스턴스 값을 부모에게 노출 시킴

:: 결합도가 증가함을 인지 

 

useImperativeHandle – React

The library for web and native user interfaces

ko.react.dev

 

1.1 사용

  const passwordConfirmRef = useRef(null)
  const passwordConfirmField = register('passwordConfirm', { // 
    required: { value: true, message: '비밀번호 확인이 필요합니다.' },
    validate: {
      equals: (value, { password }) => { return password === value || '비밀번호가 일치하지 않습니다.' },
    }
  })

  useImperativeHandle(passwordConfirmField.ref, () => passwordConfirmRef.current)

- 1) 사용할 ref와 사용하고 있던 register 추출 및 정의


 useImperativeHandle(passwordConfirmField.ref, () => passwordConfirmRef.current)

1) passwordConfirmField.ref를 passwordConfirmRef.current로 바꿔서,

2) 부모가 passwordConfirmRef를 통해 해당 input 요소에 접근할 수 있도록 덮어쓰기를 함


<input
	id="passwordConfirm"
    type="password"
    className={clsx("input", { "error-border": errors?.passwordConfirm })}
    {...passwordConfirmField} // register
    ref={passwordConfirmRef} // 빨대 용도의 ref
/>

위에서의 연결을 통해 passwordConfirmRef로 해당 register에 접근하여 input에 대한 정보를

 

<button
	type='button'
	onClick={() => {
    	if (passwordConfirmRef?.current?.type === 'password') {
			passwordConfirmRef.current.type = 'text'
		} else {
			passwordConfirmRef.current.type = 'password'
		}
		console.log(passwordConfirmRef?.current)
}}>
	패스워드 보기
</button>

이와 같이 조절이 가능하다

 

더보기
전체 코드 
function App() {
  const {
    register,
    formState: { errors, dirtyFields },
    handleSubmit,
  } = useForm()
  const passwordConfirmRef = useRef(null)
  const passwordConfirmField = register('passwordConfirm', { // 
    required: { value: true, message: '비밀번호 확인이 필요합니다.' },
    validate: {
      equals: (value, { password }) => { return password === value || '비밀번호가 일치하지 않습니다.' },
    }
  })

  useImperativeHandle(passwordConfirmField.ref, () => passwordConfirmRef.current)
  
  return (
    <>
      <h3 style={{ margin: 0 }}>유저 추가하기</h3>
      <form className='form-wrapper' onSubmit={handleSubmit((data) => console.log(data))}>
        <>
          <div>
            <label htmlFor='passwordConfirm' className='input-label'>패스워드 확인: </label>
            <span className='input-area'>
              <input
                id='passwordConfirm'
                type='password'
                className={clsx('input', { 'error-border': errors?.passwordConfirm })}
                {...passwordConfirmField}
                ref={passwordConfirmRef}
              />
            </span>
            <div className={clsx({ 'error-text': errors?.passwordConfirm })}>
              {errors?.passwordConfirm?.message}
            </div>
          </div>
        </>
        <button
          type='button'
          onClick={() => {
            if (passwordConfirmRef?.current?.type === 'password') {
              passwordConfirmRef.current.type = 'text'
            } else {
              passwordConfirmRef.current.type = 'password'
            }
            console.log(passwordConfirmRef?.current)
          }}>
            패스워드 보기
        </button>
        <button type='submit'>저장하기</button>
      </form>
    </>
  )
}

export default App​

 

이런 덮어쓰기가 아닌 다른 포커싱용 사용은

 

[React Hook Form] useRef 연결하여 사용하기

React-use-Form을 사용하다 보면, useRef를 연결하여 사용할 일(스크롤 관련이나, 포커싱 관련 이벤트를 처리할 때)이 종종 있다.예를 들어, textarea의 인풋 창을 수정할 때 value의 높이에 따라 textarea의

velog.io

를 참고하자!

 


참고

ASAC 수업자료

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/03   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
글 보관함