Developer/React

React , 예제로 살펴보는 useState와 이벤트 처리

단님 2024. 6. 11. 21:22
728x90

과제 1.
사용자가 - 버튼을 누르면 -1 감소
사용자가 + 버튼을 누르면 +1 증가
0보다 작아지면 alert 경고창 활성화
20 보다 커지면 alert 경고창 활성화화 함께 0으로 초기화
import { useState } from "react";
export default function Body (){
    const [count , setCount] = useState(0);
    
    const onDecrease = ()=> {
        if(count<=0){
            alert('!!! 용량이 너무 작아요 ');
            setCount(0);
        }else{
            setCount(count-1)
        }
    };
    
    const onIncrease = ()=>{
        if(count>=20){
            alert('!!!용량 초과 리셋됩니다.');
            setCount(0);
        }else{
            setCount(count+1);
        }
    };

    
    return(
        <>
        <h2>
            과제 1
        </h2>
        <button
        onClick={onDecrease}>
            -
        </button>
        <span>count : {count} </span>
        <button 
        onClick={onIncrease}>
            +
        </button>
        </>
    )

    
}

두가지의 버튼이벤트가 존재.

 

상태값을 관리하는 useState 가 존재한다.

버튼 클릭할때마다 상태가 변하도록 설정.

 

버튼이벤트가 유사함으로 이와같이 함축적용 가능.

case 1. 매개변수의 활용

    const change = (how) => {
        if (how == '-') {
            if (count <= 0) {
                alert('!!! 용량이 너무 작아요');
                setCount(0);
            } else {
                setCount(count - 1);
            }
        } else {
            if (count >= 20) {
                alert('!!!용량 초과 리셋됩니다.');
                setCount(0);
            } else {
                setCount(count + 1);
            }
        }
    };
        <button
        onClick={()=>change('-')}>
            -
        </button>
        <span>count : {count}</span>
        <button 
        onClick={()=>change('+')}>
            +
        </button>

클릭이벤트에 매개변수를 전달하면서

매개변수가 어떤것인지를 판별하여  + 일때 - 일때의 작동을 달리함.

 

case 2. target이 되는 name으로 판별

    const change = (e) => {
        let id = e.target.name;
        console.log(id);
        if ( id == '-') {
            if (count <= 0) {
                alert('!!! 용량이 너무 작아요');
                setCount(0);
            } else {
                setCount(count - 1);
            }
        } else {
            if (count >= 20) {
                alert('!!!용량 초과 리셋됩니다.');
                setCount(0);
            } else {
                setCount(count + 1);
            }
        }
        };
        <button
        name="-"
        onClick={change}>
            -
        </button>
        <span>count : {count}</span>
        <button
        name="+"
        onClick={change}>
            +
        </button>

버튼에 name 값을 준 다음 판별.

 

 

과제 2.
사용자가 버튼이 5회 클릭된 후에 값을 5증가.
0보다 작아지면 alert 경고창 활성화
20 보다 커지면 alert 경고창 활성화화 함께 0으로 초기화

 

case.1 useState의 2개 사용. (첫시도 , 랜더링이 자주일어남으로 지양해야함.)

import { useState } from "react";
export default function Body (props){
    // state Test 1 : 정의 , 출력
    const [count , setCount] = useState(0);
    const [count2 , setCount2] = useState(0);
    
    const onDecrease = ()=> {
        setCount2(count2+1);
        if(count2==4){
            if(count<=0){
                alert('용량 모잘라');
                setCount(0);
            }else{
                setCount(count-5);
                setCount2(0);
            }
        }
    };
    const onIncrease = ()=>{
        setCount2(count2+1);
        if(count2==4){
            if(count>=20){
                alert('용량 초과');
                setCount(0);
            }else{
                setCount(count+5);
                setCount2(0);
            }
        }
    };

    
    return(
       <>
        <h2>
        1. 정의 , 출력
        </h2>
        <button
        onClick={onDecrease}>
            -
        </button>
        <span>count : {count}</span>
        <button 
        onClick={onIncrease}>
            +
        </button>
        </>
    )

    
}

카운트 횟수를 관리하는 const [count2 , setCount2] = useState(0);

count2 의 값이 5가 되었을때 값을 리셋하고 , count 의 값을 5 증가.

0과 20에 대한 조건식은 똑같이 적용.

 

단점 => 버튼이벤트로 인해 값이 변화되지 않음에도 불구하고 상태값의 변화로 인해 함수가 계속 리랜더링 되는 상황 발생. 

단점을 보완하기 위해 useState를 1개를 사용하고 카운트 횟수를 관리하는 값을 다른 변수에 담았다.

 

case 2. useState 1개와 함수내의 변수 사용.

import { useState } from "react";
export default function Body (props){
    // state Test 1 : 정의 , 출력
    const [count , setCount] = useState(0);
    let count2=0;
    
    const onDecrease = ()=> {
        count2++;
        if(count2==5){
            if(count<=0){
                alert('용량 모잘라');
                setCount(0);
            }else{
                setCount(count-5);
                //count2=0;
            }
        }
    };
    const onIncrease = ()=>{
        count2++;
        if(count2==5){
            if(count>=20){
                alert('용량 초과');
                setCount(0);
            }else{
                setCount(count+5);
                //count2 =0;
            }
        }
    };

    
    return(
       <>
        <h2>
        1. 정의 , 출력
        </h2>
        <button
        onClick={onDecrease}>
            -
        </button>
        <span>count : {count}</span>
        <button 
        onClick={onIncrease}>
            +
        </button>
        </>
    )

    
}

함수내에 count2 를 선언과 동시에 초기화(0)을 하고,

클릭할때마다 count2의 값을 증가.

count2 의 값이 5가 된다면 , count2의 값을 리셋해주고 count의 값을 증가시킴.

랜더링 자체가 함수의 재 실행이기 때문에

count2 =0; 을 따로 해주지 않아도 재실행 되면서 count2 가 0 으로 초기화.

 

count2와 count의 차이를 랜더링의 시점으로 바라본다면 해결된다.

이는 랜더링최적화에서 중요한 부분이고 이를 활용할 줄 알아야 할것같다.

 

case3 . 동일 함수의 합침.

    const [count , setCount] = useState(0);
    let count2=0;
    
    const change = (e) => {
        let id = e.target.name;
        console.log(id);
        console.log(count2);

        if ( id == '-') {
            count2--;
            
            if (count <= 0) {
                alert('!!! 용량이 너무 작아요');
                setCount(0);
                count2 = 0;
                } else {
                    if(count2 == -5){
                        setCount(count - 1);
                    }
                }
        } else {
            count2++;
            if(count2 ==5){
                if (count >= 20) {
                    alert('!!! 용량이 너무 많아요');
                    setCount(count+5);
                } else {
                    setCount(count + 1);
                }
            }
        }
        };
        <button
        name="-"
        onClick={change}>
            -
        </button>
        <span>count : {count}</span>
        <button
        name="+"
        onClick={change}>
            +
        </button>