티스토리 뷰
🍕클래스형 컴포넌트 와 함수형 컴포넌트 차이
- 컴포넌트의 생명주기를 관리하는 LIfeCycle api를 클래스형에서는 componentDidMount / componentDidUpdate / componentWillUnmount 3개의 함수로 쪼개놨다면 함수형에서는 useEffect라는 hook에 3가지 기능을 같이 수행하도록 만들어놨다.
함수형 컴포넌트에서 리렌더링된다는 것은 "해당 함수를 다시 호출한다"라는 의미 -> useEffect를 사용하지 않고 빠르게 확인해보고 싶다면 해당 컴포의 최상단에 console.log("나 렌더링됨"); 하고 state값을 변경하는 이벤트를 발생시켜주면 된다.
아래는 그 예시코드
const One = () => {
//구조분해 할당
const [oneValue, setValue] = React.useState("hi");
//함수형 컴포에서 리렌더링이 일어나고 있는 지 궁금하다면 console에 찍어보자
//함수형 컴포에서 리렌더링이 된다는 것은 "이 함수를 다시 호출할거야" 랑 같은 의미
console.log("나 렌더링되었어!");
return (
<div className="One">
<p>{oneValue}</p>
<button
onClick={() => {
setValue("state 변경완료!");
}}
>
변경 버튼
</button>
</div>
);
};
- 라이프 사이클 메소드를 처리할 때 클래스형의 경우는 this.props 를 사용했는데 여기서 props는 (함수형에서도 공통적으로)불변한 값이지만 컴포넌트의 this 는 변경 가능한 값이다. 즉, 여러 이벤트를 발생시키고 렌더링 이전에 다른 페이지로 이동(부모 컴포가 다른 props로 렌더링시킴)하는 일이 생기면 this가 가리키는 객체(문맥상 컴포넌트)가 새 페이지의 객체로 되어버린다.
- 함수형은 this를 사용하지 않기 때문에 위와같이 렌더링하기 전에 페이지 전환이 일어나도 전달받는 props의 값이 변하지 않고 그대로 출력된다.
🍕Hook은 함수형 컴포넌트에서 사용한다.
Why? 함수형 컴포는 클래스형 컴포와 다르게 리액트의 기능을 그냥 사용할 수 없기 때문이다.
함수형 컴포에서도 클래스형 컴포와 동일하게 상태값을 관리한다거나 라이프 사이클 메서드를 사용한다든가 등등.. 의 리액트 기능들을 사용할 수 있도록 하기 위해서 태어났음
Hook은 리액트 16.8버전부터 지원
- Hook은 그냥 자바스크립트 함수입니다. (공식문서에서도 hook에 대해서 이렇게 설명하고 있습니다.)
🌞리액트 hook 사용시 기본 규칙 2가지
- 함수형 컴포넌트에서만 쓸 수 있다. (리액트 함수*에서만 사용가능)
- *리액트함수란? 리액트 규칙을 따르는 함수
- 컴포넌트의 최상위에서만 호출할 수 있다.
🌞Hook의 종류
리액트 hook의 종류는 '기본 hooks' 와 '추가 hooks' 여러 개로 구성되어 있습니다.
자세한 내용은 React 공식 문서를 통해 확인이 가능합니다.
이 Hook들 중에 사용 빈도가 높은 친구들에 대해서 알아봅시다.
- useState
- useEffect
- useCallback
- useRef
🌚React.useState - 컴포넌트의 state값 상태값을 관리하는 hook
🌚React.useEffect - 컴포넌트의 사이드 이펙트(외부 요청을 보낸다거나 이벤트리스너를 구독하기 구독 해제 등등..) 관리를 위해서 사용하는 hook
- 위에서 언급했듯이 클래스형 컴포넌트에서 componentDidMount / componentDidUpdate / componentWillUnmount 의 기능을 하나에 담은게 useEffect hook입니다.
- useEffect 메소드는 한 컴포넌트에서 여러 개를 사용해도 된다! -> 의존성 배열에 들어간 값에 따라 해야할 일(콜백함수)이 다르면 여러 개를 사용하면 되겠죠?
- 2개의 인자를 갖습니다.
- 콜백함수 - 컴포넌트가 화면에 그려질 때(렌더링, 리렌더링 초함) 실행할 어떤 함수, 리턴값으로 클린업 함수를 반환한다. *클린업 함수는 필수는 아니고 필요에 따라 effect에 정리(clean-up)가 필요한 경우에는 함수를 반환
- dependency array(의존성 배열) - 해당 배열에 넣은 (의존)값이 변할 때만 콜백함수가 실행된다. //해당 배열에 넣은 값이 변하지 않는다면 리렌더링이 일어나도 useEffect의 콜백함수는 실행되지 않는다.
//useEffect()사용하기
//아래의 예시에는 배열에 의존값이 없으니 처음 한번만 실행됩니다.
React.useEffect(() => {
console.log("나 여기있어!");
}, []);
React.useEffect(() => {
console.log(oneValue);
}, [oneValue]);
- 클린업 함수가 필요한 경우?
공식문서ver) 외부 데이터에 구독(subscription)을 설정해야 하는 경우를 생각해보겠습니다.
이런 경우에 메모리 누수가 발생하지 않도록 정리(clean-up)하는 것은 매우 중요합니다.
결론적으로 클린업함수는 메모리 누수 방지를 위한 것입니다.
쉬운 설명ver) 컴포넌트가 화면에서 사라질 때에 마지막으로 정리하는 기능을 합니다.
e.g) p태그에 마우스오버 이벤트를 붙여놓고(이벤트 리스너로) 나중에 컴포넌트가 화면에서 사라진다면 내 메모리에 이벤트 리스너 구독정보를 가지고 있을 필요가 없다. 그래서 해당 컴포가 없어질 거 같으면 구독해제를 클린업함수에서 해주는 것이다.
자세한 내용은 아래를 참고하시길 바랍니다.
리액트 공식문서: https://ko.reactjs.org/docs/hooks-effect.html#effects-with-cleanup
🌚React.useCallback( 콜백함수, 의존성 배열)
- 해당 함수는 콜백의 *메모이제이션된 버전을 반환합니다. 메모이제이션된 버전은 콜백의 의존성(두번째 인자인 배열에 담겨있는 애들)이 변경됐을 때만 변경된다.
- 의존성 값의 배열이 콜백에 인자로 전달되는 것은 아닙니다.
- 위의 useEffect와 같은 구성을 가지고 있는 hook이다. 또한, useMemo와 비슷한 hook이라고 하네요.
- useMemo는 특정 결과값을 재사용할 때 사용하는 반면, useCallback은 특정 함수를 새로 만들지 않고 재사용하고 싶을 때 사용하는 함수입니다. -> memo는 값을 반환 / callback은 함수를 반환
- useCallback과 useMemo은 자식 컴포넌트의 불필요한 렌더링을 최적화할 수 있습니다.
- useCallback(fn, deps)은 useMemo(() => fn, deps)와 같습니다.
- TIP) 해당 컴포 내부에서만 사용할 때는 잘 사용하지 않으며 부모 컴포에서 자식 컴포에 부모의 함수를 전달해줄 때 사용함
메모이제이션(memoization)은 컴퓨터 프로그램이 동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술이다.
동적 계획법의 핵심이 되는 기술이다. 메모이제이션이라고도 한다.
// 부모 컴포A에서 아래의 함수를 logger에 담아준다.
const logger = React.useCallback(() => {
console.log("나 메모이제이션된 함수야!");
}, []);
// (중략)
return
// (중략)
// props로 logger를 자식 컴포에 전달해준다.
<Two logger={logger} />
// 여기부터 컴포B
// 자식 컴포B에서 props로 받아와서 사용해준다. 끝
export const Two = ({ logger }) => {
return <button onClick={logger}>콘솔 남기기</button>;
};
🌚React.useRef - ref 객체를 다루기 위한 hook
- 쉽게 말하면 도플갱어 박스
- 어떤 값을 넣어주면 그 값으로 초기화된 변경 가능한 어떤 ref객체를 반환해준다.
- useRef가 반환해준 ref객체는 똑같이 생겼지만 다른 값이여서 변경을 해도 괜찮다! -> 변경 시 컴포넌트가 리렌더링 X
const input_ref = React.useRef(null);
//중략
return
<button onClick={() => {
console.log(input_ref.current.value);
//ref객체는 값을 변경할 수 있고 컴포넌트의 리렌더링도 일어나지 않는다.
input_ref.current.value = "";
}}> 인풋값 보기</button>
<div>
<input ref={input_ref} />
</div>
'Frontend > WIL😎' 카테고리의 다른 글
[WIL | 항해99] 마지막주차 회고 실전 프로젝트 끝!( feat. FE tip) (1) | 2022.08.10 |
---|---|
[WIL | 항해99] 7주차 회고 미니프로젝트 끝 실전 시작 (0) | 2022.06.26 |
[TIL] 20220604 리액트 프로젝트 세팅(CRA 사용 x), 가상 DOM (0) | 2022.06.04 |
[WIL | 항해99] 3주차 회고 DOM과 서버리스(serverless) (0) | 2022.05.30 |
[WIL | 항해99] 2주차- ECMAScript가 뭔가요(ES3 ~ ES8 추가 기능 설명) (0) | 2022.05.22 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 항해99추천비추천
- 틸드와 캐럿
- is()
- getServerSideProps
- 프리온보딩 프론트엔드 챌린지 3월
- 원티드 프리온보딩 프론트엔드 챌린지 3일차
- && 셸 명령어
- fs모듈 넥스트
- reactAPI
- grid flex
- 항해99프론트후기
- 원티드 3월 프론트엔드 챌린지
- 원티드 FE 프리온보딩 챌린지
- 형제 요소 선택자
- getStaticPaths
- aspect-ratio
- 타입스크립트 DT
- nvm 설치순서
- text input pattern
- ~ ^
- 원티드 프리온보딩 FE 챌린지
- tilde caret
- Prittier
- 타입스크립트 장점
- nvm경로 오류
- 프리렌더링확인법
- 항해99프론트
- D 플래그
- float 레이아웃
- 부트캠프항해
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함