Frontend/React

[React] Lifecycle / useEffect

seong's log 2024. 3. 24. 19:55

컴포넌트의 Lifecycle 

mount : 페이지에 장착

update : 재 랜더링

unmount : 필요없을 경우 제거

 

useEffect 

랜더링 후 (html 코드가 다 실행 된 후) 실행 됨

=> 시간이 오래걸리는 어려운 작업을 useEffect () 안에 넣기

( 어려운 연산, 서버에서 데이터 가져오는 작업, 타이머장착하는 작업 ) 

 

import { useEffect, useState } from "react";
import { Container, Row, Col } from "react-bootstrap";
import { useParams } from "react-router";
import styled from "styled-components";

function Detail(props){

    let [count, setCount] = useState(0)
    let [remove, setRemove] = useState(true)
    // Detail 컴포넌트가 mount, update 될 때 실행
 
    useEffect(()=>{
        let a = setTimeout(()=>{setRemove(!remove)}, 2000)
        //console.log("dd")

       /* return()=>{
            clean up function : 
            useEffect 가 실행되기 전에 실행 됨
            기존 코드를 제거하고 싶을 때 사용

            clearTimout(a) 
        }*/

    },[count]) 
    // mount 시 최초 실행 1번 + count 가 변경 될 때마다 코드가 실행 됨 
    // mount 시 최초 실행 1번만 실행하고 싶으면 [] 안에 아무것도 적지 않기
    // [] 적지 않으면 재렌더링 될 때마다 실행 됨

    // setTimeout(()=>{실행할 코드},1000) : 타이머 주기 => 1초이내에 실행할 코드


    let{id} = useParams();
    if(id >= props.shoes.length){
        return <div>없는상품입니다.</div>
    }
    return(
        <div>
            <Container>
                {remove && <div className="alert alert-warning">
                    2초이내 구매시 할인
                </div>}
                <button onClick={()=>{ setCount (count+1)}}>버튼{count}</button>
                <Row>
                    <Col md={6}>
                        <img src={"https://codingapple1.github.io/shop/shoes"+(props.shoes[id].id+1)+".jpg"} width="80%"/>
                        <h4>{props.shoes[id].title}</h4>
                        <p>{props.shoes[id].content}</p>
                        <p>{props.shoes[id].price}원</p>
                        <button className="btn btn-danger">주문하기</button>
                    </Col>                                       
                </Row>
            </Container>
        </div>
    )
   
}

export default Detail;

 

input 숫자가 아닌 경우 alert 창 띄우기

import { useEffect, useState } from "react";
import { Container, Row, Col } from "react-bootstrap";
import { useParams } from "react-router";
import styled from "styled-components";

function Detail(props){

    let [count, setCount] = useState(0)
    let [input, setInput] = useState("")
    let [alert, setAlert] = useState(false)

    useEffect(()=>{
        var numberChk = /^[0-9]*$/;
        if(!input.match(numberChk)){
            setAlert(true)
        }else{
            setAlert(false)
        }  
    },[input]) 

    let{id} = useParams();
    if(id >= props.shoes.length){
        return <div>없는상품입니다.</div>
    }
    return(
        <div>
            <Container>
                <button onClick={()=>{ setCount (count+1)}}>버튼{count}</button>
                <Row>
                    <Col md={6}>
                        <img src={"https://codingapple1.github.io/shop/shoes"+(props.shoes[id].id+1)+".jpg"} width="80%"/>
                        <h4>{props.shoes[id].title}</h4>
                        <p>{props.shoes[id].content}</p>
                        <p>{props.shoes[id].price}원</p>
                        <button className="btn btn-danger">주문하기</button>
                    </Col>                                       
                </Row>
                <input type="text" onChange={(e)=>{setInput(e.target.value)}}></input>
                { alert && <div>숫자만 입력가능합니다</div>}
            </Container>
        </div>
    )
   
}

export default Detail;