when to validate?
onSubmit
- 사용자가 입력을 진행하는 중에 경고 메세지를 보여주지 않는다.
- 불필요한 warning을 피할 수 있지만, 입력값에 대한 유효성 피드백이 다소 늦어진다.
onBlur
- submit과 마찬가지로, 불필요한 경고 메세지를 보여주지 않을 수 있다.
- form의 touched 상태를 관리할 때 유용하다.
onChange
- 사용자의 모든 key stroke에 대해 유효성 검사를 진행한다.
- 빠른 피드백을 보여주는 동시에, 불필요한 경고 메세지(값을 전부 입력하기도 전에 유효성 평가)를 띄운다.
useRef vs. useState
// useState
const [name, setName] = useState('');
const changeHandler = (e) => {
setName(e.target.value);
};
// useRef
const nameRef = useRef('');
const submitHandler = (e) => {
nameRef.current.value;
// setName(''); good ⭕
// nameRef.current.value = ''; bad ❌
};
- useState
- onChange
- instant validation
- 값을 입력한 후에 인풋을 초기화해야 한다면 2 way binding과 함께 state를 사용하는 것이 낫다.
- useRef
- onSubmit
- 폼이 제출되었을 때만 입력 값이 필요하다면 ref를 사용하는 것이 낫다.
- ref.current.value = ' ' | 바닐라 js를 이용해 DOM을 직접 조작하는 것으로, 리액트가 지양해야 하는 부분이다.
client side validation
- your frontend code is visible to everyone in the browser
- 클라이언트 사이드의 js 코드는 사용자에 의해 편집될 수 있다.
- 따라서 브라우저의 유효성 검사는 good UX를 위함일 뿐, 실제 데이터를 저장하는 서버 측에서도 유효성 검사를 진행해야 한다.
input validation
const [name, setName] = useState('');
const [isNameFocused, setNameFocus] = useState(false);
const isNameValid = name.trim().length > 0;
const invalid = !isNameValid && isNameFocused;
const onChangeHandler = (e) => {
setName(e.target.value);
};
const onBlurHandler = () => {
setNameFocus(true);
};
const onSubmitHandler = (e) => {
e.preventDefault();
setNameFocus(true);
if (!isNameValid) return;
setName('');
setNameFocus(false);
};
const classes = invalid ? 'form-control invalid' : 'form-control';
- name/ focus state가 변경될 때 마다 코드가 재평가된다.
- 따라서 isNameValid와 같은 state를 만들 필요 없이 변수로 관리한다.
- name value와 focus 상태를 조합해서 invalid 상태를 정의한다.
form validation
모든 input 값이 유효하면, form 전체가 유효하다고 볼 수 있다.
// 1. state
const [isFormValid, setFormValid] = useState(false);
useEffect(() => {
setFormValid(isNameValid && isAgeValid && ...)
}, [isNameValid, isAgeValid, ...])
// 2. variable
const isFormValid = isNameValid && isAgeValid ...
- form valid 값을 이용해서 버튼의 disabled 활성화 여부를 결정할 수 있다.
useInput
const useInput = (validate) => {
const [inputValue, setInputValue] = useState('');
const [isInputFocused, setInputFocus] = useState(false);
const isInputValueValid = validate(inputValue);
const inputError = !isInputValueValid && isInputFocused;
const onChangeHandler = (e) => {
setInputValue(e.target.value);
};
const onBlurHandler = () => {
setInputFocus(true);
};
const initInput = () => {
setInputValue('');
setInputFocus(false);
};
return {
inputValue,
isInputValueValid,
inputError,
onChangeHandler,
onBlurHandler,
initInput,
};
};
'Study > React' 카테고리의 다른 글
react-firebase | authentication (0) | 2022.08.16 |
---|---|
Deployment | firebase hosting (0) | 2022.07.04 |
custom Hooks (0) | 2022.06.24 |
HTTP Request (0) | 2022.06.23 |
Optimization | how does react work? (0) | 2022.06.22 |