엘리스 SW 엔지니어 트랙 10주차(2)

ChanghyeonO·2023년 6월 22일
0
post-custom-banner

이번에는 리액트 Hook에 대해 알아보자.
나도 이해하는데에 조금 어려움을 느껴 블로그 게시물을 작성하며 하나하나 복습할거다.

Hook이란?

-컴포넌트에서 데이터를 관리(state)하고 데이터가 변경될 때 상호작용(Effect)을 하기 위해 사용한다.

Hook의 등장 배경

-기존에는 컴포넌트 내에서 State와 생명주기를 관리하기 위해 Class 컴포넌트 사용이 필수적이었다.
그러나 개발자가 느끼기에 복잡한 Class 컴포넌트를 보완하고 함수 컴포넌트에서 클래스 컴포넌트 기능을 구현하기 위해 React 16.8 버전에 추가된 것이 Hook이다.

사용시 유의사항

-Hook은 리액트 함수(컴포넌트)에서만 사용이 가능하다.
-Hook의 이름은 반드시 use로 시작해야한다.
-최상위 Level에서만 Hook을 호출 할 수 있다.
(if, for문 안쪽, 콜백함수 내에서 호출 금지)

State Hook & Effect Hook이란?

State Hook

function App() {
	const [state이름,setState이름] = useState(초기값)
}

-useState는 컴포넌트 내 동적인 데이터를 관리할 수 있는 hook이다.
-최초에 useState가 호출될 때 초기값으로 설정되며 이후 재 렌더링이 될 경우 무시된다.
-state는 읽기 전용이기 때문에 직접 수정 금지.
-state 변경은 useState를 이용한다.
-state가 변경되면 자동으로 컴포넌트가 재렌더링 된다.

function App() {
	const [title, setTitle] = useState("");
    
    //변경할 state값을 직접 입력하는 방식
    setTitle("Hello")
    
    //현재 값을 매개변수로 받는 함수 선언, return 값이 state에 반영된다.
    setTitle((current)=> {
    	return current + "World";
    })
 }
    

-state를 변경하기 위해서는 setState 함수에 직접 값을 입력하거나 현재 값을 매개변수로 받는 함수를 전달한다.
이때 함수에서 return 되는 값이 state에 반영된다.

Effect Hook

function App() {
	useEffect(EffectCallback, Deps)
}

-Effect Hook을 사용하면 함수 컴포넌트에서 side effect를 수행할 수 있다.
-컴포넌트가 최초로 렌더링 될 때, 지정한 State나 Prop이 변경될 때마다 이펙트 콜백 함수가 호출된다.

-Deps: 변경을 감지할 변수들의 집합(배열)
-EffectCallback: Deps에 지정된 변수가 변경될 때 실행할 함수

funcion App() => {
	const [count, setCount] = useState(0);
   
  	useEffect(()=>{
    	console.log('버튼을 ${count}회 클릭했습니다')
    })
    
return (
	<div>
    	<button onClick={()=>{setCount(count+1)}}>클릭</button>
    </div>

-Effect Hook을 사용하면 함수 컴포넌트에서 side effect를 수행할 수 있다.
-컴포넌트가 최초로 렌더링될 때, 지정한 State나 Props가 변경될 때마다 이펙트 콜백 함수가 호출된다.

function App() {
	useEffect(() => {
    	//State가 변경될 때, 컴포넌트를 렌더링 할 때
        const intervalId = setInterval(()=>{
        	console.log('안녕하세요')
        },1000)
        
        //컴포넌트를 재 렌더링 하기 전에, 컴포넌트가 없어질 때
        return ()=>{
        	clearInterval(intervalId);
        }
    },[])
 ....

-useEffect의 이펙트 함수 내에서 다른 함수를 return 할 경우 state가 변경되어 컴포넌트가 다시 렌더링 되기 전과 컴포넌트가 없어질 때 호출할 함수를 지정하게 된다.

여러 Hook 종류들

-useMemo

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b])

-useCallback

const memoizedCallback = useCallback(() => {
	doSomething(a, b);
   },
   [a, b],
);

-useRef

const refContainer = useRef(initialValue);

useMemo란?

function App() {
	const [firstName, setFirstName] = useState('철수')
    const [lastName, setLastName ] = useState('김')
    
    //이름과 성이 바뀔 때마다 풀네임을 메모이제이션
    const fullName = useMemo(()=>{
    	return `${firstName} ${lastName}`
    }, [firstName, lastName])
 };

-지정한 State나 Props가 변경될 경우 해당 값을 활용해 계산 된 값을 메모이제이션 하여 재렌더링시 불필요한 연산을 줄인다.
-useMemo의 연산은 렌더링 단계에서 이루어지므로 시간이 오래 걸리는 로직은 작성하지 않는 것이 좋다.

useCallback이란?

function App() {
	const [firstName, setFirstName] = useState('철수')
    const [lastName, setLastName ] = useState('김')
    
    //이름과 성이 바뀔 때마다 풀네임을 메모이제이션
    const getfullName = useCallback(()=>{
    	return `${firstName} ${lastName}`
    }, [firstName, lastName])
    
    return <>{fullname}</>
 };
 

-함수를 메모이제이션 하기 위해 사용하는 Hook, 컴포넌트가 재렌더링될 때 불필요하게 함수가 다시 생성되는 것을 방지한다.
-useMemo(()=>fn,deps)와 useCallback(fn,deps)는 같다.

useRef란?

function App() {
	const inputRef = useRef(null)
    const onButtonClick = () => {
    	inputRef.current.focus()
    }
    return (
    	<div>
        	<input ref={inputRef} type="text" />
            <button onClick={onButtonClick}>input으로 포커스</button>
        </div>

-컴포넌트 생애 주기 내에서 유지할 ref객체를 반환한다.
-ref객체는 .current라는 프로퍼티를 가지며 이 값을 자유롭게 변경할 수 있다.
-일반적으로 리액트에서 DOM Element에 접근 할 때 사용한다.(DOM Element의 ref속성 이용)
-useRef에 의해 반환된 ref 객체가 변경되어도 컴포넌트 재렌더링 x

###커스텀 Hook
-자신만의 Hook을 만들면 컴포넌트 로직을 함수로 뽑아내 재사용이 가능하다.
-UI요소의 재사용성을 올리기 위해 컴포넌트를 만드는 것 처럼, 로직의 재사용성을 높이기 위해서는 Custom Hook을 제작한다.

function useMyHook(args) {
	const [status, setStatus] = useState(null);
    ...
    return status;
};

-한 로직이 여러 번 사용될 경우 함수를 분리하는 것 처럼 Hook을 만드는 것일 뿐, 새로운 개념이 아니다.
-Hook의 이름은 'use'로 시작해야한다.
-한 Hook 내의 state는 공유되지 않는다.

profile
꾸준한 기록을 통해, 좋은 개발자가 되겠습니다.
post-custom-banner

0개의 댓글