[React] 리액트 훅

cool_kim·2021년 7월 10일
0

React

목록 보기
4/8
post-thumbnail

: 컴포넌트에 기능을 추가할 때 사용하는 함수
ex) 컴포넌트에 상탯값 추가 or 자식 요소에 접근

  • 클래스형 컴포넌트보다 장점이 많으며 리액트 팀에서도 훅에 집중함

대표적인 리액트 훅
1. useState : 상탯값 추가
2. useEffect : 부수효과 처리(서버 API호출, 이벤트 핸들러 등록 등)

useState

const [count, setCount] = useState(0);

  1. 초기값을 넣어 호출

  2. 배열 반환 : 첫번째 아이템에는 상태값, 두번째 아이템에는 상태값 변경 함수

  3. 상태값 변경 함수는 비동기이면서 배치(batch)로 처리됨

    • 만약 동기로 처리되면 하나의 상태값 변경 함수가 호출될 때마다 화면을 다시 그리기 때문에 성능 이슈가 생김
    • 상태값 변경 함수를 동기로 처리하고 매번 화면을 다시 그리지 않는다면 UI데이터와 화면간의 불일치가 발생하여 혼란
    • 동기로 처리하려면 상태값 변경 함수 안에 함수를 입력 setCount(v => v + 1);
      → 처리되기 직전의 상태값을 매개변수로 받기 때문에 잘 동작함
    • 리액트에서 관리하지 않는 외부에서 호출하는 경우에는 배치로 동작하지 않음
      ex) window.addEventListener('click', onclick);
      → 상태값 변경 함수를 호출할 때마다 렌더링 발생
      • 외부에서 처리 될 때도 배치로 처리되게 하기
        → ubstable_batchedUpdates() 사용
        function onClick() {
        	ReactDOM.unstable_batchedUpdates(() => {
        		setCount(v => v + 1);
        		setCount(v => v + 1);
        	});
        }
  4. 상태값 변경 함수는 호출한 순서대로 적용됨

  5. 여러개의 상태값을 하나의useState로 관리 할 수 있음(객체 이용)
    const [state, setState] = useState({ name: '', age: 0 });
    상태값 변경 함수를 호출할 때는 전체 객체를 새로 입력해 줘야함
    onChange={e => setState({ ...state, name: e.target.value })}
    📍 어러 상태값을 관리할 때는 useState보다는 useReducer가 더 적합



useEffect

모든 부수 효과는 useEffect훅에서 처리하는게 좋음

useEffect(() => {
	document.title = `업데이트 횟수: ${count}`;
});
  1. 첫번째 매개변수에 함수 작성(부수효과 함수) → 함수는 렌더링 결과가 실제 돔에 반영되고 비동기로 호출

    ✔️ userId를 속성값으로 받아 api를 호출해 해당 유저의 정보를 가져온 다음, user 상태값을 변경

export default function Profile({ userId }) {
	const [user, setUser] = useState(null);

	//userId가 변경될 때만 부수효과함수 실행
	useEffect(() => {
		getUserApi(userId).then(data => setUser(data));
	}, [userId]);
	return (
		<div>
			{!user && <p>사용자 정보를 가져오는 중...</p>}
			{user && (
				<>
					<p>{`name is ${user.name}`}</p>
					<p>{`age is ${user.age}`}</p>
				</>
			)}
		</div>
	);
}

const USER1 = { name: "mike", age: 23 };
const USER2 = { name: "jane", age: 31 };

//userId가 홀수일때 USER1리턴 짝수일때 USER2리턴
function getUserApi(userId) {
	return new Promise[res => {
		setTimeout(() => {
			res(userId % 2 ? USER1 : USER2);
		}, 500);
	});
}
  1. 두번째 매개변수로 배열 입력(의존성 배열)
    • 이 배열에 있는 값이 변경될 때만 부수효과 함수 실행
    • 의존성 배열에 빈배열을 입력하면 부수 효과 함수는 마운트 된 이후에 한번만 호출
    • 부수효과 함수에서 사용한 변수(컴포넌트의 상태값, 속성값, 컴포넌트 내부에서 정의된 지역변수, 지역함수) → 의존성 배열에 작성해 줘야함
      📍 const [user, setUser] = useState(null);setUser 값(상태값 변경 함수)은 변하지 않기 때문에 배열에 추가 안해도 됨.
    • 의존성 배열의 값이 항상 변경될 때는 useCallback훅을 이용해 메모리에이션 기능 이용
    • 꼭 필요한 경우에만 입력해야함

  2. 부수효과 함수 반환값
    • useEffect에서 새로운 함수가 반환 될때는 다음 부수효과 함수가 호출되기 직전에 호출 or 컴포넌트가 사라지기(unmount) 직전에 호출 → 적어도 한번은 호출

📍 이벤트 핸들러를 등록할 때 useEffect 부수효과 함수로 작성
📍 이벤트 핸들러 해제할 때 useEffect 반환 함수로 작성

useEffect(() => {
	window.addEventListener('resize', onResize);
	return() => {
		window.removeEventListener('resize', onResize);
	};
}, []);



커스텀 훅 만들기

  • 훅의 이름은 use로 시작하는 것이 좋음
export default function useUser(userId) {
	const[user, setUser] = userState(null);

	useEffect(() => {
		getUserApi(userId).then(data => setUser(data));
	}, [userId]);
	return user;
}

//사용할때
const user = useUser(userId);

⇒ userId가 변경되면 훅 내부에서 자동으로 api를 호출해서 사용자 데이터 가져올 것

👍 비동기 방식으로 동기 방식처럼 사용 가능!

profile
FE developer

0개의 댓글