컴퓨터 프로그래밍/Next.js

[Next.js] EventHandler, useState 선언 및 수정, Array,Object state 변경

한33 2025. 2. 10. 23:48

💡 EventHandler

<button onClick={()=>{ console.log(1) }}>버튼</button>

 

button 에 EventHandler 를 달아주려면 onClick={()=>{ JavaScript Code}} 이런 식으로 해야한다.

물론 client component 에서만 JavaScript 가 실행 가능하니까 페이지 상단에 'use client' 를 달아주자.


💡 useState

'use client'
import { useState } from "react";

export default function List() {
    let [count, changeCount] = useState(0)
    let products = ['Tomatoes', 'Pasta', 'Coconut']
    return (
        <div>
            <h4 className="title">상품 목록</h4>
            {
                products.map((product, i) => {
                    return (
                        <div className="food" key={i}>
                            <img src={`/food${i}.png`} className="food-img"></img>
                            <h4>{products[i]} $40</h4>
                            <button onClick={()=>{changeCount(count-1)}}>-</button>
                            <span>{count}</span>
                            <button onClick={()=>{changeCount(count+1)}}>+</button>
                        </div>
                    )
                })
            }
        </div>
    );
}

 

변수를 선언하는 방법 이외에 useState 를 활용하는 방법도 있다.

🔧 useState 선언

1. 페이지 상단에 client component 선언

2. import { useState }

3. let [변수이름작명, 함수작명] = useState(변수에넣을값);

 

순서로 useState 를 설정해준다.

 

🔧 왜 변수 선언대신 useState 를 사용하는가?

일반 변수는 변경되어도 변수가 들어있는 html 에 자동으로 반영되지 않는다.

반면 state 가 변경되면 state 가 들어있는 html 도 자동으로 재렌더링 된다. ( html 을 지웠다가 다시 만든다. )

 

→ 자주 변경되는 값들만 useState 로 지정하면 좋다.

 

🔧 useState 수정

<button onClick={()=>{changeCount(count+1)}}>+</button>

 

EventListner={()=>{함수작명(JavaScript 를 활용해 변수이름작명 수정)}}


💡 Array, Object state 변경

'use client'
import { useState } from "react";

export default function List() {
    let [count, changeCount] = useState([0, 0, 0])
    let products = ['Tomatoes', 'Pasta', 'Coconut']
    return (
        <div>
            <h4 className="title">상품 목록</h4>
            {
                products.map((product, i) => {
                    return (
                        <div className="food" key={i}>
                            <img src={`/food${i}.png`} className="food-img"></img>
                            <h4>{products[i]} $40</h4>
                            <button onClick={()=>{
                                let copy = [...count]
                                copy[i]--
                                changeCount(copy)
                            }}>-</button>
                            <span>{count[i]}</span>
                            <button onClick={()=>{
                                let copy = [...count]
                                copy[i]++
                                changeCount(copy)
                            }}>+</button>
                        </div>
                    )
                })
            }
        </div>
    );
}

 

상품이 3개니까 수량이 저장되어야할 곳도 3개가 필요해서 Array 를 사용했다.

 

이후에 onClick 안에 들어갈 함수를 설정했는데, 저 함수를 밖으로 빼냈다.

'use client'
import { useState } from "react";

export default function List() {
    let [count, changeCount] = useState([0, 0, 0])
    let products = ['Tomatoes', 'Pasta', 'Coconut']

    // 수량 감소 함수
    const decreaseCount = (index) => {
        let copy = [...count];
        copy[index]--;
        changeCount(copy);
    }

    // 수량 증가 함수
    const increaseCount = (index) => {
        let copy = [...count];
        copy[index]++;
        changeCount(copy);
    }

    return (
        <div>
            <h4 className="title">상품 목록</h4>
            {
                products.map((product, i) => {
                    return (
                        <div className="food" key={i}>
                            <img src={`/food${i}.png`} className="food-img"></img>
                            <h4>{products[i]} $40</h4>
                            <button onClick={() => { decreaseCount(i)}}>-</button>
                            <span>{count[i]}</span>
                            <button onClick={() => {increaseCount(i)}}>+</button>
                        </div>
                    )
                })
            }
        </div>
    );

}

 

decreaseCount 와 increaseCount 함수를 보면 Array 를 copy 에 복사한 것을 볼 수 있다.

🔧왜그런가?

리액트의 동작 원리때문에 그렇다.

state변경함수() 를 쓰는 경우

컴퓨터는 기존state == 신규state 이렇게 먼저 검사를 해보고 같으면 state 변경을 하지 않는다.

 

안에 array 와 object 구성 요소를 바꿔도 state 변경이 되지 않을 것이다. 왜냐하면 javaScript 원리 상

 

 

1. 자바스크립트는 array/object 자료를 하나 만들면

예를 들어서 let arr = [1,2,3] 이렇게 만들면 

[1,2,3] 자료는 RAM이라는 공간에 몰래 저장이 되고

let arr 변수엔 그 자료가 어디있는지 가리키는 화살표만 담겨있다.

 

 

2. array/object 자료를 수정한다고 해도 

화살표타고 들어가서 RAM에 있던 값이 수정될 뿐

변수에 담긴 화살표는 변하지 않는다. 

그래서 아까 기존state == 신규state 비교하면 같다고 나오는 것이다.

(==로 비교하면 변수에 저장된 값인 화살표만 비교해줍니다)

 

 

3. 심지어 array/object 자료를 복사해도 화살표만 복사된다. 

 

let copy = [...수량]
수량[0]++
수량변경(copy)

 

때문에 완전한 복사본을 뜻하는 [...수량]

을 이용해 복사본을 만들어 주면 아예 별개의 array 또는 object 가 되기 때문에 화살표도 다르게 된다.

그래서 state 가 변경된다.