React hook form의 watch를 이용해서 입력 여부 확인하기

이주희·2022년 3월 21일
5

Libraries

목록 보기
3/21

공식 문서
[MDN]

react hook form을 사용해서 만든 페이지에 input값을 토대로 입력값이 있으면 버튼에 색을 추가하고, 값을 지우면 색을 제거하는 UI를 만들기 위해 useform의 값을 반환하는 함수가 필요했다.
watch와 getValues 두가지가 있었고, 처음에 getValues를 먼저 사용했는데, getValues 함수는 값을 바꿀 때 바로 스타일이 적용되지 않았다,, 그래서 watch로 변경했더니 입력/삭제와 동시에 바로 원하던대로 색을 추가하거나 제거해주는 함수가 잘 실행되었다!
찾아보니, getValues는 watch와 다르게 리렌더링을 일으키지 않는 것이 원인인 것 같다. setState 같은 자식...

watch()

  • 지정된 인풋을 관찰(watch)하고, 그 값들을 반환하며, 렌더링 할 대상을 결정할 때 유용합니다.

  • defaultValue가 정의되지 않은 경우, register가 아직 호출이 안되었기 때문에 watch의 첫번째 렌더링에서는 undefined 을 반환합니다. 하지만, 두번째 인수로 defaultValue를 설정하여 값을 반환 할 수 있습니다.

  • useForm 에서 defaultValues로 정의가 되어 있다면, 첫번째 렌더링에서 defaultValues에 적용된 내용을 반환합니다.

getValues()

  • 폼의 값을 읽을 때 사용합니다. watch 와 다르게 getValues​​ 는 리랜더링을 일으키거나 입력값의 변화를 구독하지 않는다는 것입니다. 이 함수는 아래의 방식으로 사용합니다.
  • getValues​​(): 폼의 전체 값을 읽습니다.

  • getValues​​('test'): 폼 안의 개별 인풋 값을 읽습니다.name.

  • getValues​​(['test', 'test1']): 인풋의 name 속성을 지정하여 여러 값을 읽습니다.


watch()를 활용해서 4개의 값이 모두 입력되면 버튼의 색깔 바꾸기

1. BoardWrite.container.js

onChange에 이벤트 함수를 호출해서 검증할 값들이 비어있는지 확인한다.
값이 비어있으면 isActive에 true를, 비어있지 않으면 false로 값을 변경한다.
해당 이벤트가 일어나는 input의 값은 watch로 검증하면 함수가 종료되고 나서 렌더링이 이루어져 입력과 동시에 값이 바뀌지 않고, 다른 input의 값을 변경되어야 값을 읽어온다.
따라서, 해당 input의 값은 e.target.value로 불러온다.

    const [isActive, setIsActive] = useState(true);
    const onChangeWriter = (e)=>{
        e.target.value &&  watch("password") &&  watch("title") &&  watch("contents") ? setIsActive(false) : setIsActive(true)
    }
    const onChangePassword = (e)=>{
        e.target.value &&  watch("writer") &&  watch("title") &&  watch("contents") ? setIsActive(false) : setIsActive(true)
    }
    const onChangeTitle = (e)=>{
        e.target.value &&  watch("writer") &&  watch("password") &&  watch("contents") ? setIsActive(false) : setIsActive(true)
    }
    const onChangeContent = (e)=>{
        e.target.value &&  watch("writer") &&  watch("password") &&  watch("title") ? setIsActive(false) : setIsActive(true)
    }

2. BoardWrite.presenter.js

각각의 input의 onChange를 호출해서 위에서 선언한 함수를 넣어줬다.

<InputWrapper>
	<Label>작성자<Required>*</Required></Label>
	<ShortInput {...props.register("writer", { required: true })} onChange={e=>props.onChangeWriter(e)}  type="text" placeholder="이름을 적어주세요."/>
	{props.errors.writer && <Error>이름을 입력해주세요.</Error>}
</InputWrapper>
<InputWrapper>
	<Label>비밀번호<Required>*</Required></Label>
	<ShortInput {...props.register("password", { required: true })} onChange={e=>props.onChangePassword(e)}  type="password" placeholder="비밀번호를 입력해주세요."/>
	{props.errors.password && <Error>비밀번호를 입력해주세요.</Error>}
</InputWrapper>
<InputWrapper>
	<Label>제목<Required>*</Required></Label>
	<Input {...props.register("title", { required: true })} onChange={e=>props.onChangeTitle(e)}   type="text" placeholder="제목을 작성해주세요."/>
	{props.errors.title && <Error>제목을 입력해주세요.</Error>}
    <Label>내용<Required>*</Required></Label>
	<ContentInput {...props.register("contents", { required: true })} onChange={e=>props.onChangeContent(e)}  type="text" placeholder="내용을 작성해주세요."/>
	{props.errors.contents && <Error>내용을 입력해주세요.</Error>}
</InputWrapper>

3. BoardWrite.style.js

isActive의 값이 true이면 배경색을 red로, 그렇지 않으면 yellow(#FFD600)를 줬다.

export const SubmitButton = styled.button`
  background-color: ${(props) => props.isActive ? "red" : "#FFD600;"};
	.
	.
	.
`
profile
🍓e-juhee.tistory.com 👈🏻 이사중

0개의 댓글