본문 바로가기
React

React : study(4) { React State }

by yaans 2023. 2. 8.

 

State

react의 변수 역할

state가 바뀌면 화면을 새로 렌더링해준다

import { useState } from 'react';

state 속성을 사용하기 위해서는 리액트 패키지에서 useState 함수를 불러와야 한다

 

const [num, setNum] = useState(1);

parameter로 초기값( == 1)을 전달 받은 후 함수가 실행되고 나면

결과 요소를 값 2개 배열 형태로 반환한다

 

※ 배열의 두 요소 중,

1번째는 state, 즉 현재 변수의 값의 이름을 지어준다

2번째는 setter 역할의 메소드 명을 지어준다 -> 이 메소드를 호출할 때 마다 state가 바뀐다

 

 

해당 속성을 적용하기 위해서는 변수를 컴포넌트에 명시

<MultiDice color='red' num={num} />

state로 만든 {num}에 적용하여 변수가 바뀔 때 마다 컴포넌트는 새로 렌더링이 된다

 

function random(n) {
    return Math.ceil(Math.random() * n);
}

function App() {
    const [num, setNum] = useState(1);

    const handleRollClick = () => {
        const nextNum = random(6);
        setNum(nextNum);
   	};
    
    
    return (
        <Button onClick={handleRollClick}>CHANGE</Button>
        
        <MultiDice color='red' num={num} />
	);
 ...   
}

위에 적용한 num 변수는

랜덤 숫자 생성을 위한 random(n) 함수와 handleRollClick 이벤트 핸들러로 인해 setNum (setting)된다

 

이제 버튼을 클릭할 때마다 숫자가 바뀌는 모습을 확인할 수 있다

 

결과 확인

기본 상태

버튼 클릭 시 -> 랜덤으로 숫자가 변경

 

 

배열, 객체같은 참조형 state

자바스크립트에도 존재하는 기본형(primitive type) vs 참조형(reference type) 자료형의 차이

 

랜덤으로 출력되는 숫자 값 num의 변화를 배열에 담아 출력해보겠다

function App() {
    const [num, setNum] = useState(1);
    // 배열 변수를 위한 useState 생성
    const [gameHistory, setGameHistory] = useState([]);


    const handleRollClick = () => {
        const nextNum = random(6);
        setNum(nextNum);
        
        // 배열에 값을 push
        gameHistory.push(nextNum);
        setGameHistory(gameHistory);
        
    };

    const handleClearClick = () => {
        setNum(1);
        // clear를 위한 새 배열을 세팅
        setGameHistory([]);
    };

    return (
        <div>
            <Button onClick={handleRollClick}>CHANGE</Button>
            <Button onClick={handleClearClick}>CLEAR</Button>
            
            ...
            
            <MultiDice color='red' num={num} />
            
            ...
            
            <div>
                <h2>기록</h2>
                <p>{gameHistory.join(', ')}</p>
            </div>
        </div>
    );
}
export default App;     // export를 통해 이 컴포넌트를 다른 파일에서도 활용 가능

 

배열형 변수를 사용할 때 주의점

배열 변수 gameHistory는 참조형이기 때문에,

배열 안에 값이 계속 추가되고 삭제가 되더라도 참조형 변수가 실제로 가지고 있는 "배열 주소값"은 일치한다

 

실제로 버튼 클릭 이벤트 핸들러에 배열형 변수의 상태가 변화하는 명령어만 있다면, 컴포넌트는 다시 랜더링되지 않는다...

const handleRollClick = () => {
        const nextNum = random(6);
        // setNum(nextNum); -> "num" state의 변화를 인식해서 렌더링되어 왔던 것...
        
        // 해당 이벤트 핸들러에 gameHistory의 변화만 두면 페이지의 클릭 이벤트가 작동하지 않는다
        gameHistory.push(nextNum);
        setGameHistory(gameHistory);
        
    };

 

만약 다른 state의 도움 없이 배열형 변수만 사용하여 컴포넌트를 렌더링하고 싶다면?

원인인 참조형인 배열 변수의 주소값을 변경하자

기존 배열 변수의 값을 추가, 삭제 하는 것이 아니라,

setter에 매번 새 주소값을 가진, "새 배열"을 할당한다면 useState가 변화를 인식하고 컴포넌트를 새로 렌더링해준다

 

결과 확인

다른 useStatue 값 없이 잘 세팅되는 배열 변수

댓글