한 번에 하나의 걱정만!
관심사의 분리란 단위 별로 하나의 관심사만 있도록 분리하는 과정.
코드는 짧고 간단해야 한다!
코드가 단순해질수록 재사용이 쉽고, 유지보수가 용이해지고, 테스트 코드 작성이 간단해짐.
const loginForm = document.getElementsByClassName('loginForm')[0];
const loginBtn = document.getElementById('loginBtn');
const handleInput = () => {
const idValue = document.getElementById('id').value;
const pwValue = document.getElementById('pw').value;
const isIdValid = idValue.length > 1;
const isPasswordValid = pwValue.length > 1;
const isLoginInputValid = isIdValid && isPasswordValid;
loginBtn.disabled = !isLoginInputValid;
loginBtn.style.opacity = isLoginInputValid ? 1 : 0.3;
loginBtn.style.cursor = isLoginInputValid ? 'pointer' : 'default';
};
const init = () => {
loginForm.addEventListener('input', handleInput);
};
init();
handleInput함수 내에 너무 많은 기능이 들어있다.
const loginForm = document.getElementsByClassName('loginForm')[0];
const loginBtn = document.getElementById('loginBtn');
const validateForm = () => { // 1
const idValue = document.getElementById('id').value;
const pwValue = document.getElementById('pw').value;
const isIdValid = idValue.length > 1;
const isPasswordValid = pwValue.length > 1;
return isIdValid && isPasswordValid;
}
const handleButtonActive = (isButtonActive) => { // 2
loginBtn.disabled = !isButtonActive;
loginBtn.style.opacity = isButtonActive ? 1 : 0.3;
loginBtn.style.cursor = isButtonActive ? 'pointer' : 'default';
}
const handleLoginInput = () => { // 3
const isFormValid = validateForm();
handleButtonActive(isFormValid);
}
const init = () => {
loginForm.addEventListener('input', handleLoginInput);
};
init();
기존의
handleInput을 기능별로 세분화하였다.
기존에 사용하던 훅인 useState 나 useEffect 또한 React의 내장 메소드이다.
상태 관리를 위해 훅을 사용했던 것처럼, fetch처럼 Hook을 사용하고 재사용이 잦은 기능을 커스터마이징하여 컴포넌트처럼 사용하는 것이 커스텀 훅이다.
useFetch 이런거 겁나 편해보임..
// UserStatus.js
import React, { useState } from 'react';
const UserStatus = () => {
const [isActive, setIsActive] = useState(false);
const handleToggle = () => {
setIsActive((prev) => !prev);
};
return (
<>
<h1>현재 사용자의 상태입니다.</h1>
<span>{isActive ? '사용 중' : '사용 안 함'}</span>
<button onClick={handleToggle}>사용 상태 변경</button>
</>
);
};
export default UserStatus;
해당 코드는 로직과 UI가 결합되어 있다.
// UserStatus.js
import React, { useState } from 'react';
const useToggle = (initialValue = false) => { // 1
const [state, setState] = useState(initialValue); // 2
const handleToggle = () => { // 3
setState((prev) => !prev);
};
return [state, handleToggle]; // 4
};
const UserStatus = () => {
const [isActive, changeStatus] = useToggle(); // 5
return (
<>
<h1>현재 사용자의 상태입니다.</h1>
<span>{isActive ? '사용 중' : '사용 안 함'}</span> // 6
<button onClick={changeStatus}>사용 상태 변경</button>
</>
);
};
export default UserStatus;
UserStatus 컴포넌트에서 토글 기능을 useToggle 이라는 함수로 빼냈다. 재사용성이 높아보이니 이 함수를 커스텀 훅으로 활용해주자.
// useToggle.js
import { useState } from 'react';
const useToggle = (initialValue = false) => {
const [state, setState] = useState(initialValue);
const handleToggle = () => {
setState((prev) => !prev);
};
return [state, handleToggle];
};
export default useToggle;
useToggle.js 파일을 생성해 토글 기능을 분리해주었다.
// UserStatus.js
import React from 'react';
import useToggle from './useToggle';
const UserStatus = () => {
const [isActive, changeStatus] = useToggle();
return (
<>
<h1>현재 사용자의 상태입니다.</h1>
<span>{isActive ? '사용 중' : '사용 안 함'}</span>
<button onClick={changeStatus}>사용 상태 변경</button>
</>
);
};
export default UserStatus;
결과적으로 useState를 사용했을 때처럼 디스트럭쳐링해서 사용하게 된다.
wecode 세션
이해는 어렵지 않지만 활용이 어려워보인다. 많이 써봐야겠다.