본문 바로가기

Languages/React

[React] 2-1. State

728x90
반응형

0. State

현재 리액트를 통해 버튼을 클릭했을 때 클릭한 횟수만큼 화면에 출력하는 어플리케이션을 만들고 있다. 이를 위해선 당연히 클릭 횟수를 저장하는 공간이 필요하다. 

 

좋지 않은 방법과 좋은 방법이 있다. 좋지 않은 방법부터 살펴보자.

 

1. Bad

클릭 횟수를 저장하는 변수 counter를 생성한다. React에서는 {}를 통해 변수를 그대로 html에 출력시킬 수 있다.

 

클릭 시 counter를 증가시키는 countUp 함수도 생성한다. 다음 버튼을 클릭할 때마다 countUp을 실행한다.

<script type="text/babel">
    const root = document.getElementById("root");
    let counter = 0;
    function countUp(){
        counter = counter+1;
    }
    const Container = () =>(
        <div>
            <h3>Total clicks : {counter}</h3>
            <button onClick={countUp}>
                Click me
            </button>
        </div>
    );
    
    ReactDOM.render(<Container/>, root);
</script>

그러나 버튼을 아무리 클릭해도 숫자는 증가하지 않는다. 실제로 counter는 증가하고 있는데도 말이다. counter는 증가하지만 화면 새로고침을 하지 않기 때문에 초기화면 그대로 유지되는 것이다. 즉 버튼을 클릭하고 결과를 보고 싶다면 버튼 클릭시마다 화면을 새로 렌더링 해줘야한다. 다음 코드와 같이 말이다.

<script type="text/babel">
    const root = document.getElementById("root");
    let counter = 0;
    function countUp(){
        counter = counter+1;
        ReactDOM.render(<Container/>, root);
    }
    const Container = () =>(
        <div>
            <h3>Total clicks : {counter}</h3>
            <button onClick={countUp}>
                Click me
            </button>
        </div>
    );
    
    ReactDOM.render(<Container/>, root);
</script>

countUp함수에 Container에 대한 렌더링이 추가되었다. 이로써 버튼을 클릭할 때마다 counter가 증가하고 새로 렌더링되어 버튼 클릭 횟수를 바로 확인할 수 있다.

 

이 방법의 단점은 무엇일까? 렌더링 해주는 것을 까먹으면 안 된다는 것이다. 어떠한 변화가 있을 때마다 다시 렌더링을 해줘야하며 프로젝트가 커질수록 번거로울 것이다. 

 

훨씬 더 좋은 방법을 알아보자.

 

 

2. set State

데이터가 변화할 때마다 렌더링해줘야 한다는 불편함이 있었다. 이러한 불편함을 해결하기 위해 이번에는 React.js 어플 내에서 데이터를 보관하고 자동으로 렌더링 해주는 방법을 배워본다. 즉 React를 더 활용해보자.

 

다시 처음으로 돌아간다. 현재 코드는 다음과 같다.

<script type="text/babel">
    const root = document.getElementById("root");
    
    function App(){
        return(
            <div>
                <h3>Total clicks : 0</h3>
                <button>
                    Click me
                </button>
            </div>
        );
    }
    ReactDOM.render(<App/>, root);
</script>

 

React의 useState라는 것을 사용해볼 것이다. data라는 변수를 React.useState로 저장하고 출력하면 다음과 같다.

const data = React.useState(0);
console.log(data);

크기가 2인 배열이다. 0번 째 배열에 있는 것이 count, 1번 째 배열에 있는 것이 countUp 역할을 맡을 것이다. 즉 앞에 있는 것은 변수, 뒤에 있는 것은 함수이다. 함수는 변수의 값을 바꾸는 역할을 한다. React.useState의 모양이 그렇다. 

 

참고로 두 개의 변수를 한 번에 저장할 수도 있다. 

const [counter, modifier] = React.useState(0);

위는 자바 스크립트 문법인데 이렇게 쓰면 counter와 modifier라는 변수에 React.useState의 변수와 함수가 한 번에 저장된다. 

 

modifier는 두 가지 역할을 한다. 하나는 counter에 새로운 값을 저장하는 것이고 또 다른 하나는 counter에 대하여 렌더링을 해주는 것이다. 즉 useState를 활용하면 개발자가 별도로 렌더링해주는 번거로움을 없앨 수 있다.

 

버튼을 클릭했을 때 실행되는 함수를 만들고 그 안에 modifier를 통해 counter의 값을 변경한다. 다음과 같이 말이다.

<script type="text/babel">
    const root = document.getElementById("root");
    
    function App(){
        const [counter, countUp] = React.useState(0);
        const onClick = () =>{
            countUp(counter+1);
        };
        return(
            <div>
                <h3>Total clicks : {counter}</h3>
                <button onClick={onClick}>
                    Click me
                </button>
            </div>
        );
    }
    ReactDOM.render(<App/>, root);
</script>

Click me 버튼을 클릭하면 html의 숫자만 바뀐다. 자동으로 렌더링 된다.

개발자는 최초에 한 번만 렌더링을 해주고 React의 기능을 통해서 이후에 변경되는 값에 대한 렌더링은 React가 자동으로 해주는 것이다.

 

이것으로 초기 목표였던 바닐라JS를 React로 대체하였다. 

 

 

3. State Functions

위에서 counterUp을 할 때 counter에 대해서 1씩 더해주어 사용하였다. 

const onClick = () =>{
	countUp(counter+1);
};

이 방법도 괜찮지만 counter라는 변수가 의도치않게 변경되어 원하지 않는 값으로 변경될 수도 있는 위험이 있다. 따라서 다음과 같이 작성하는게 더 안전한다.

const onClick = () =>{
	countUp((current)=>current+1);
};

왜냐하면 current는 React가 현재 값이라는 것을 보장하기 때문이다. 즉 현재 변수 값을 바탕으로 계산하여 새로운 값을 만들고 싶다면 아래 current를 이용하여 함수를 사용하는 방법이 훨씬 안전한 방법이다.

728x90
반응형

'Languages > React' 카테고리의 다른 글

[React] 1. React 기본  (0) 2021.12.12
[React] 0. React  (0) 2021.12.12