4. React 컴포넌트(3) - State 알아보기(React Hooks 사용)

2023. 3. 20. 22:58React/개념정리

https://ko.reactjs.org/docs/state-and-lifecycle.html

https://reactjs.org/docs/hooks-reference.html#usestate

 

1. state란?

- 일반적으로, 컴포넌트의 내부에서 변경가능한 데이터를 관리해야할 때 사용

- 프로퍼티(props)의 특징 : 컴포넌트 내부에서 값을 바꿀 수 없음

    값을 바꾸어야하는 경우 >> state를 사용

- 값을 저장하거나 변경할 수 있는 객체. 보통 이벤트와 함께 사용 됨

- 컴포넌트에서 동적인 값 >> state >>동적인 데이터를 다룰 때 사용됨

※ 참고
리액트 16.8 이전 버전에서는 함수형 컴포넌트에서는 상태를 관리할 수 없었다.
즉 State, Life Cycle 등등 이 없기 떄문에 클래스형 컴포넌트를 사용 했었다. 

리액트 16.8부터 Hooks 라는 기능이 도입되면서 함수형 컴포넌트에서도 상태를 관리할 수 있게 되었다. 
useState Hook을 사용하여 State 사용이 가능하다.

2. 사용방법?

0. 들어가기 앞서 어떤 상황에 React에선 state를 사용하면 좋을지 예제를 통해 생각해 보자.

ex)

import React, { useState } from 'react';

const Main = () => {
    let myName = "GodDaeHee";

    function changeName() {
        myName = myName === "GodDaeHee" ? "KimDaeHee" : "GodDaeHee";
        console.log(myName);
    }

    return (
        <div>
			<h1>안녕하세요. {myName} 입니다.</h1>
			<button onClick={changeName}>Change</button>
        </div>
    );
};

export default Main;

 - Change 버튼을 클릭 하면 console.log에 값이 찍히는 것을 볼 수 있지만, 화면출력은 변경되지 않는다.

 - 예전엔 changeName함수를 다음과 같이 작성하여 직접 렌더링 방식으로 작성 했었을 것 이다.

const Main = () => {
    let myName = "GodDaeHee";

    function changeName() {
        myName = myName === "GodDaeHee" ? "KimDaeHee" : "GodDaeHee";
        console.log(myName);
        document.getElementById("name").innerText = myName;
    }

    return (
        <div>
			<h1>안녕하세요. <span id="name">{myName}</span> 입니다.</h1>
			<button onClick={changeName}>Change</button>
        </div>
    );
};

 - 하지만 물론 react 컴포넌트에서는 이또한 화면 렌더링이 바뀌지 않는다.

 - react에서는 컴포넌트에서 동적인 값을 상태(state)라고 부르고 이를 사용하여 변경 하면 되는데 한번 살펴 보도록 하자.
 - useState를 사용하여 함수형 컴포넌트에서 상태 관리를 하는 방법을 알아 보도록 하자.

 

※ 참고
https://ko.reactjs.org/docs/hooks-overview.html

 

1. 선언방법

 - react 모듈에서 { useState }를 불러오고 useState()를 선언해서 사용하면 된다.
 - useState의 변수값이 바뀌면 컴포넌트가 새롭게 렌더링 된다.

const [state, setState] = useState(initialState);
const [ 데이터, 데이터변경함수 ] = useState(초기값(생략가능));

ex)

import React, { useState } from 'react';

const Main = () => {
	// let myName = "GodDaeHee"; // useState를 사용하여 변경
	const [ myName, setMyName ] = useState("GodDaeHee") 

    function changeName() {
        /*
		myName = myName === "GodDaeHee" ? "KimDaeHee" : "GodDaeHee";
        console.log(myName);
        document.getElementById("name").indderText = myName;
		*/
		setMyName(myName === "GodDaeHee" ? "KimDaeHee" : "GodDaeHee");
    }

    return (
        <div>
			<h1>안녕하세요. {myName} 입니다.</h1>
			{/* <button 
				onClick={() => {
					setMyName(myName === "GodDaeHee" ? "KimDaeHee" : "GodDaeHee");
				}}
			>Change</button> */}
            <button onClick={changeName}>Change</button>
        </div>
    );
};

export default Main;

 - 클릭시 마다 화면 렌더링이 바뀌는 것을 볼 수 있다.

 

 - 또다른 진부한 count 예제도 살펴보고 가면 좋을 것 같다.

 

ex)

import React, { useState } from 'react';

const Main = () => {
    const [ cnt, setCnt ] = useState(0)
    const updateCnt = () => setCnt(cnt + 1);
    const clearCnt = () => setCnt(0);
    return (
        <div>
            클릭한 횟수는 {cnt}번 입니다.
            <div>
                <button onClick={updateCnt}> 클릭해 보세요! </button>
                <button onClick={clearCnt}> 초기화 하기! </button>
            </div>
        </div>
    );
};

export default Main;

 - 클릭시 count up 되는 부분, 0으로 정상적으로 초기화 된다.

 

2. 객체(Object)도 상태변수(State Value)로 사용 가능하다.

ex) 하기와 같이 객체를 상태 변수로 사용해도 동일하게 동작 한다.

import React, { useState } from 'react';

const Main = () => {
    const [ state, setState ] = useState({cnt : 0})
    const updateCnt = val => 
    setState({
        ...state,
        [val] : state[val] + 1
    })
    const { cnt } = state
    return (
        <div>
            클릭한 횟수는 {cnt}번 입니다.
            <div>
                <button onClick={updateCnt.bind(null, 'cnt')}> 클릭해 보세요! </button>
            </div>
        </div>
    );
};

export default Main;
더보기

binding이란?

프로젝트 경험이 거의 없었을 때는 this를 binding한다는 말 조차 이해가 가지 않았었다. javascript기본서에서 call, apply, bind가 나오면 머리가 아팟다. binding이란 도대체 뭘까?

javascript의 함수는 각자 자신만의 this라는 것을 정의한다. 예를 들어 자기소개를 하는 함수를 만들기 위해 say()이라는 함수를 만든다고 하자.

const say = function() {
  console.log(this); // 여기서 this는 뭘까?
  console.log("Hello, my name is " + this.name);
};

say();

실행해보면

window객체가 나타난다. 기본적으로 this는 window이기 때문이다. 사실 참 어려운게, 꼭 window라고만 말할 수는 없다. this는 객체 내부, 객체 메서드 호출시, 생성자 new 호출시, 명시적 bind시에 따라 바뀌기 때문이다.

어찌되었든 우리는 say함수에서 Window객체를 사용하고 싶지 않다. 즉, this를 그때 그때 알맞은 객체로 바꿔서 this값에 따라 인사말이 할 것이다. 이 것이 this의 binding이다. 명시적으로 위의 this를 Window가 아닌 다른 객체로 바꿔주는 함수가 call, apply, bind이다.

call과 apply

say함수의 this를 변경하고 싶다면, 당연히 this를 대체할 객체가 있어야 한다. 코드를 조금 수정해서 아래와 같이 만들었다.

call과 apply는 함수를 호출하는 함수이다. 그러나 그냥 실행하는 것이 아니라 첫 번째 인자에 this로 setting하고 싶은 객체를 넘겨주어 this를 바꾸고나서 실행한다.

첫 번째 실행인 say("soeul")의 경우는 say가 실행 될 때 this에 아무런 setting이 되어있지 않으므로 this는 window객체이다.

두 번째 실행인 say.call(obj, "seoul");의 경우와 세 번째 실행인 say.apply(obj, "seoul")은 this를 obj로 변경시켰으므로 원하는 값이 나온다.

call과 apply의 유일한 차이점은, 첫 번째 인자(this를 대체할 값)를 제외하고, 실제 say에 필요한 parameter를 입력하는 방식이다. call과는 다르게 apply함수는 두 번째 인자부터 모두 배열에 넣어야 한다.

bind

bind함수가 call, apply와 다른 점은 함수를 실행하지 않는다는 점이다. 대신 bound함수를 리턴한다. 이 bound함수(boundSay)는 이제부터 this를 obj로 갖고 있기 때문에 나중에 사용해도 된다. bind에 사용하는 나머지 rest 파라미터는 call과 apply와 동일하다.

출처

- https://wooooooak.github.io/javascript/2018/12/08/call,apply,bind/

 

binding의 개념과 call, apply, bind의 차이점 · 쾌락코딩

binding의 개념과 call, apply, bind의 차이점 08 Dec 2018 | javascript basic this es6 binding이란? 프로젝트 경험이 거의 없었을 때는 this를 binding한다는 말 조차 이해가 가지 않았었다. javascript기본서에서 call, app

wooooooak.github.io

참고자료

3. useState를 호출하여 반환된 업데이트 함수는 setState와 유사하게 사용 가능 하다.

ex)

import React, { useState } from 'react';

const Main = () => {
    const [ cnt, setCnt ] = useState(0)
    // const updateCnt = () => setCnt(cnt + 1);
    // const clearCnt = () => setCnt(0);
    return (
        <div>
            클릭한 횟수는 {cnt}번 입니다.
            <div>
            <button onClick={() => setCnt(prevCnt => prevCnt + 1)}> 클릭해 보세요! </button>
            <button onClick={() => setCnt(0)}> 초기화 하기! </button>
            </div>
        </div>
    );
};

export default Main;

 

ex) Main 컴포넌트를 3번 호출 해보자.

import React, { Component } from 'react';
import Main from './component/Main';
import Wrapper from './component/Wrapper';

function App() {
  return (
    <div>
      <Main />
      <Main />
      <Main />
    </div>
  );
}

export default App;

 

 - 호출한 컴포넌트별로 상태관리가 가능한 것을 확인할 수 있을 것이다.

 - 아주 간단히 몇가지 예제를 통해 컴포넌트의 상태 관리하는 방법을 살펴 보았다.

 

출처

https://goddaehee.tistory.com/301

 

[React] 4. React 컴포넌트(3) - State 알아보기(React Hooks 사용)

4. React 컴포넌트(3) - State 관리 안녕하세요. 갓대희 입니다. 이번 포스팅은 [ React 컴포넌트 내용 중 State에 대한 내용 ] 입니다. : ) https://ko.reactjs.org/docs/state-and-lifecycle.html https://reactjs.org/docs/hooks-re

goddaehee.tistory.com