본문 바로가기
react - 정리중/basic

React Hook - { useEffect }

by by-choice 2021. 11. 6.

Q. 화면이 등장하여, 2초가 지나면 alert 문구, "The maximum number of guests is 2 guests."를 삭제해보자. 단 업데이트될 때 재등장하지 않으며, 2초가 되기전 화면을 나갔다가 다시 돌아와도 2초가 유지되어야 한다.

앞서 useEffect를 배우고, 활용하여 작성해 보자.

1. uesEffect을 import 한다.

import React, { useState, useEffect } from "react"; // useEffect 추가

2. uesEffect를 변수에 담지 말고, 바로 실행시킨다.

useEffect( ()=> {
   실행될 코드~~~
} )

위 코드에서 useEffect의 "실행될 코드"가 실행되는 순간은, 1 컴포넌트가 그려질 때2 컴포넌트가 업데이트될 때이다.

컴포넌트가 업데이트 될 때마다 실행되어선 안되고 일부 state값의 업데이트가 있을 때에만 실행되길 희망한다면, 아래와 같이 state값을 활용하여 조건을 추가해 줄 수 있다. 단 조건으로 들어가는 state 변수는 useEffect보다 위에 작성되어야 한다.

let [ 조건State, 조건State변경함수 ] = useState(true);
useEffect( ()=> {
   실행될 코드~~~
}, [조건State] )

만약 아래와 같이 조건 state를 넣지 않고 빈 []으로 삽입하게 된다면, 업데이트가 되어도 실행코드를 실행하지 않겠다는 의미가 된다. 즉 useEffect는 오로지 컴포넌트가 등장할때만 내부 코드가 실행된다.

useEffect( ()=> {
   실행될 코드~~~
}, [] )

컴포넌트 <Detail />이 사라질 때 실행시키고 싶은 함수가 있다면, return을 활용하면 된다.

useEffect( ()=> {
   원하는 액션 함수()
   return function 작명(){ 사라질 때 실행할 코드~~ }
   // return ()=>{ 사라질 때 실행할 코드~~ }
} )

원하는 액션 함수는 한 개 뿐만 아니라, 2개 이상 들어 갈 수 있으며, useEffect() 하나에 다 담을 수도 있고, 나눠 담을 수도 있다. 단 실행되는 순서는 그려진 순서대로 이루어 진다.

useEffect( ()=> {
   원하는 액션 함수1()
   원하는 액션 함수2()
} )
useEffect( ()=> {
   원하는 액션 함수1()
} )
useEffect( ()=> {
   원하는 액션 함수2()
} )

3. 실행될 코드를 작성한다.

useEffect(()=>{
   let timer = setTimeout(()=>{
      alertFunc(false)
   }, 2000)
   return ()=>{
      clearTimeout(timer);
   }
}, [])
let [alert, alertFunc] = useState(true);
 {
    alert 
    ? <div className="alert alert-danger">The maximum number of guests is 2 guests. </div>
    : null
 }

import React, { useState, useEffect } from "react";
import { useParams, useHistory } from 'react-router-dom';

function Detail(props){

    useEffect(()=>{
        let timer = setTimeout(()=>{
            alertFunc(false)
        }, 2000)
        return ()=>{
            clearTimeout(timer);
        }
    }, [])

    let [alert, alertFunc] = useState(true);

    let { id } = useParams(); 
    let matchedItem = props.items.find(function(item){
        return item.id == id;
    });
    let history = useHistory();
    const imgUrl = "../images/img"+ matchedItem.id +".jpg"
    return (
        <div className="container">
            <div className="row">
                <div className="col-md-6">
                    <img src={ imgUrl } width="100%" />
                </div>
                <div className="col-md-6 mt-3">
                    {
                        alert 
                        ? <div className="alert alert-danger">The maximum number of guests is 2 guests. </div>
                        : null
                    }
                    
                    <h4>{ matchedItem.country }, { matchedItem.city }</h4>
                    <h5 className="mb-3"><b>{ matchedItem.price }</b> won</h5>
                    <button className="btn btn-dark">Reservation</button> 
                    <button className="btn btn-secondary" onClick={()=>{ history.goBack() }}>Back to main</button> 
                </div>
            </div>
        </div> 
    )
}

export default Detail;

댓글