본문 바로가기

Front-end/React

[React] 훅(Hook) - useEffect

 

 

1. 정의

- useState()와 더불어 가장 많이 사용되는 훅

- 클래스 컴포넌트에서 제공하는 함수인 componentDidMount(), componentDidUpdate(), componentWillUnmount()를 통합한 기능을 제공

-  리액트의 함수 컴포넌트에서 사이드 이펙트(Side Effect)를 수행하기 위한 훅

사이드 이펙트(Side Effect)
- 사전적으로는 부작용이라는 뜻
- 컴퓨터 프로그래밍에서는 개발자가 의도치 않은 코드가 실행되면서 버그가 나타나면 사이드 이펙트가 발생했다고 함
- 리액트에서의 사이드 이펙트는 효과 혹은 영향을 뜻하는 이펙트(Effect)의 의미에 가까움
(서버에서 데이터를 받아오거나 수동으로 DOM을 변경하는 등의 작업을 의미, 작업이 다른 컴포넌트에 영향을 미칠 수 있어 렌더링중에는 작업이 완료될 수 없고 렌더링이 끝난 후에 실행되어야 하는 작업이라 사이드 이펙트라고 부름)
- 함수의 핵심 기능과 상관없는 부가 기능으로 보면 됨

 

 

2. 사용 방법

useEffect(이펙트 함수, 의존성 배열);


// 이펙트 함수(effect function)
// 의존성 배열(an array of dependencies): 이펙트가 의존하고 있는 배열

 

- 기본적으로 이펙트 함수는 처음 컴포넌트가 렌더링 된 이후와 업데이트로 인한 재렌더링 이후에 실행됨

- 의존성 배열 안에 있는 변수 중에 하나라도 값이 변경되었을 때 이펙트 함수가 실행됨

- useEffect 실행조건 넣을 수 있는 곳이 [] 의존성 배열

let [count, setCount] = useState(0);
let [alert, setAlert] = useState(true);

useEffect(() => {
	setTimeout(() => {
    	setAlert(false)
    }, 2000)
}, [count]) // count라는 state가 변할 때만 useEffect가 실행됨

 

- 이펙트 함수가 마운트와 언마운트 시 단 한번씩만 실행되게 하려면 의존성 배열에 빈 배열([])을 넣으면 됨

(해당 이펙트가 props나 state에 있는 어떤 값에도 의존하지 않는 것이 되므로 여러번 실행되지 않음, mount시 1회만 실행됨)

let [count, setCount] = useState(0);
let [alert, setAlert] = useState(true);

useEffect(() => {
	setTimeout(() => {
    	setAlert(false)
    }, 2000)
}, [])

 

- 의존성 배열은 생략할 수 있음, 생략 시 컴포넌트가 업데이트 될 때마다 호출됨(재렌더링 마다 코드를 실행할 때)

- useEffect 안에 있는 코드는 html 렌더링 후에 동작함

(실행이 오래 걸리는 코드, 어려운 연산, 서버에서 데이터 가져오는 작업, 타이머 장착 등을  useEffect안에 작성하면 효율적)

import { useParams } from "react-router-dom";
import styled from 'styled-components';
import { useEffect, useState } from "react";

let SkyBtn = styled.button`
    background : ${ props => props.bg };
    color : ${ props => props.bg == 'black' ? 'white' : 'black'};
    padding : 10px;
`


function Detail(props) {
    // html이 렌더링 된 후에 실행되니까 실행이 오래 걸리는 코드는 useEfect안에 쓰는 것이 효율적 
    useEffect(() => {
        for(var i = 0; i < 10000; i++) {
            console.log(1);
        }
    })

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

    let {id} = useParams();

    return (
        <div className="container">
            <SkyBtn bg="skyblue" onClick={() => {setCount(count+1)}}>버튼</SkyBtn>
            <SkyBtn bg="black">버튼</SkyBtn>
            {/* <NewBtn bg="orange">버튼</NewBtn> */}

            <div className="row">
                <div className="col-md-6">
                <img src={"https://codingapple1.github.io/shop/shoes" + (props.shoes[id].id + 1) +".jpg"} width="100%" />
                </div>
                <div className="col-md-6">
                <h4 className="pt-5">{props.shoes[id].title}</h4>
                <p>{props.shoes[id].content}</p>
                <p>{props.shoes[id].price}</p>
                <button className="btn btn-danger">주문하기</button> 
                </div>
            </div>
            </div> 
    )
}

export default Detail;

 

- useEffect 동작 전에 실행되는 return () => {}

(useEffect의 return 에 들어가는 clean up function: mount 시 실행안됨, unmount 시 실행됨)

(unmount 시 1회 코드 실행 할 때 사용)

useEffect(() => {
        let timer = setTimeout(() => {
            setAlert(false);
        }
        , 2000)

        return () => {
            clearTimeout(timer);
        }
    })

 

 

'Front-end > React' 카테고리의 다른 글

[React] 훅(Hook) - useCallback  (0) 2023.09.03
[React] 훅(Hook) - useMemo  (0) 2023.09.03
[React] 훅(Hook) - useState  (0) 2023.09.03
[React] 라우팅, 라우터  (0) 2023.06.29
[React] 이미지 넣기  (0) 2023.06.29