그렇다면 포커스 해제 상태에서
어떻게 입력값을 검증할 수 있을까요?
이것을 위해서는
포커스가 해제되는 입력창에 반응해야 하는데
예를 들자면 이메일 입력창 같은 것입니다
또한 onBlur 속성과 같은 또다른 이벤트 리스닝 속성을 추가해
포커싱이 해제되는 입력에
반응하는 것도 가능한데
blur(블러) 이벤트는 빌트인 기본 브라우저 이벤트로
해당 입력이 포커스를 잃게 될 때마다 발현될 것이기 때문입니다
그러므로 우리는 여기에 새로운 이벤트 핸들링 함수로
handleEmailBlur 또는
보다 일반적인 이벤트 핸들링 함수인
handleInputBlur를 설정해두도록 하겠습니다
그리고 여기에 이렇게 식별자를
받아 주면서
새로운 상태를 관리하도록 하겠습니다
왜냐하면 이제는
단순히 입력창에 입력된 값뿐만 아니라
사용자가 해당 값을 건드렸는지의 여부도
기록하고자 하기 때문입니다
blur 이벤트가 발현되고
이 입력창이 포커스를 잃게 되면
포커스가 원래 존재했었다는 사실을
우리는 알 수 있습니다
다시 말해, 사용자가 이를 건드렸고
무언가 했다라는 것입니다
그래서 두 번째 상태가 필요해지는데
물론 우리는
여기 이렇게 이메일에 중첩된
didBlur 또는 didEdit 속성 등
처음에는 False 였다가 나중에 True 로 설정된
객체를 관리함으로
기존의 상태에 이를 병합시킬 수도 있습니다만
여기에서는 단순하게 useState를 사용해서
새로운 상태를 하나 더 만들도록 하겠습니다
그리고 다시, 처음 상태가 False인
email 속성과 password 속성을
객체로 관리하겠습니다
여기 didEdit, 그리고 setDidEdit 상태는
이 입력의 수정 여부를 기록하는 데에 쓰이는데
제 경우에는 단순히 포커스 해제를 의미하기 때문에
사용자와의 상호작용을 통해 포커스를 잃었는지를 뜻합니다
이제 이 상태를 여기에 추가했으니
이제 handleInputBlur에서
didEdit 상태를 업데이트하기 위해
이 함수 형태를 다시 사용하고
새로운 객체를 반환해서
데이터나 정보를 잃지 않도록
예전 상태를 펼치겠습니다
그리고 handleInputCharger 함수와 마찬가지로
이 구문(syntax)으로 해당 속성을 동적으로 겨냥하겠습니다
여기에서는 단순히 True로 설정해 줄텐데
인풋의 포커스가 흐려진 상태가 되면
이것이 발현될 것이기 때문이지만
원래는 False라는 것을 기억해 주시기 바랍니다
다음으로는 handleInputBlur 를
이곳에 실행시키려고 하는데
이것이 호출되는 방식을 제어하기 위해
함수로 감싸주어야 합니다
그렇게 되면 이 경우에는 email 인 식별자를
handleInputBlur로 전달할 수 있게 됩니다
그러면 이제 새로 만든 didEdit 상태를 이용해
유효성 검증을 실행할 수 있습니다
이메일의 유효성을 확인하기 위해
초기값을 유지하고 있는지를 확인하는 대신
이 체크를 유지하고 이 체크를 didEdit.email과 결합해
확인해 보겠습니다
만약 사용자가 이메일 주소를 수정했음에도
이메일이 @ 부호를 포함하고 있지 않다면
emailIsInvalid는 True가 됩니다
그리고 이와 함께
해당 검사가 구동되기 전
사용자에게 수정할 기회를 제공하기 위해
오류 메시지를 출력해 보여줍니다
이 모든 것을 저장하고
돌아가 로딩을 다시 해보면
처음부터 오류 메시지가 보이지 않는 것을 확인할 수 있습니다
타이핑을 시작해도 오류 메시지는 보이지 않지만
입력란에서 나와 포커스가 해제되면
오류 메시지가 보여집니다
입력란에 클릭을 했지만 아무것도 입력하지 않은 채
입력란 밖을 클릭해도 마찬가지 입니다
다시 타이핑을 시작하고
유효한 값이 얻어지면 오류는 사라집니다
좋은 사용자 경험이라 말할 수 있겠습니다
슬라이드를 통해 언급드렸었지만
포커싱 해제 상태에서 유효성 검증을 하게 되면
오류가 너무 오랫동안 드러나게 됩니다
이것이 무엇을 의미할까요?
말하자면 여기에서
오류 알림이 너무 오래 보여진다고 말할 수도 있을 텐데
이 오류 메세지가 있는 상태에서는
타이핑을 시작하더라도
유효한 값이 입력되어야지만 비로소 알림이 사라지기 때문입니다
물론, 여러분이 제공하고자 하는 것이
이러한 것일 수도 있지만
이는 곧, 사용자가 타이핑을 재개하자마자
해당 오류 메시지가 사라져야 한다고
생각할 수도 있다는 것을 뜻하기도 합니다
사용자가 다시 타이핑을 한다는 것은
유효한 값을 입력할 또다른 기회를 가졌다는 것이기에
사용자가 타이핑을 마치고 나서
입력창이 포커스를 잃는 시점에 검증을 다시 진행하여
유효성이 다시 확인될 때까지 해당 오류 메시지가
보여지지 않아야 한다고 생각할 수도 있습니다
그러므로 우리가 지금 가진 솔루션을
개선하는 방법은
키가 눌릴 때마다 didEdit가 업데이트 되도록 하는 것과
사용자가 타이핑을 다시 시작할 때마다
이것을 False로 리셋시키는 것이 있는데
이것은 handleInputChange로 가서
여기의 setDidEdit를 업데이트하면 됩니다
그리고 다시 이 함수 형태를 사용해서
이것을 업데이트 하고
지난 상태를 복사해서
식별자를 통해 동적인 입력과 목표로
이것을 리셋하여 False로 만들어 줍니다
이렇게 되면 사용자가 다시 타이핑을 시작할 때
입력란과 연결된
didEdit 상태 리셋됩니다
처음에는 오류 알림이 보여지지 않지만
포커스를 잃었을 때 유효하지 않은 값이 있으면
오류 메시지가 보여진다는 것입니다
그렇지만 다시 타이핑을 시작하면
오류 알림은 사라지고
유효한 값이 없는 상태로 포커스를 잃으면
오류 알림이 다시 나타나게 됩니다
그러므로 양쪽에 있어 최선이라고 할 수 있는 것은
키 입력에 따른 검증과
포커싱 해제에 따른 검증을 결합하고
사용자가 다시 타이핑을 했을 때에
해당 포커스 상태를 리셋하는 것을 통해
사용자 입력을 검증하는 것이 좋은 패턴이라 할 수 있겠습니다
그러나 입력을 유효성을 검증하는 방법으로는
양식 제출 또한 있습니다