티스토리 뷰

React.js의 State? 

- 데이터가 저장되는 곳, 값이 바뀔 데이터를 담는 곳 

-컴포넌트에서 동적인 값을 상태(state)라고 부름

-리액트의 useState 라는 함수를 이용하면 컴포넌트에서 상태를 관리할 수 있다.

why React?

-리액트를 사용하면 변경된 부분만 업데이트할 수 있다.(UI에서 바뀐 부분만 업데이트 해줌)

-react가 아닌 경우, 일반 JS를 쓴 브라우저는 노드 정보가 바뀔 때마다 노드 트리를 5단계에 걸쳐서 처음부터 다시 생성해야 한다. 반면, 리액트는 가상돔을 써서 우리 시야(UI)에 보이는 부분만 수정해서 보여주고 모든 업데이트가 끝나면 일괄로 합쳐서 실제 돔에 던져준다. (브라우저의 작동원리와 관련됨) 

* 렌더 = 렌더트리, 프론트엔트는 렌더트리 단계를 얼마나 최적화하는가가 중요하다.

 

▶변수(함수 등)를 JSX에 포함시키는 방법

- JSX 코드에 {변수명}

let anyNum = 0;
const Container = () => (
      <div>
        <h3>Total clicks : {anyNum}</h3>
        <button onClick={countUp}>Click me!</button>
      </div>
    );
  • 위의 예시코드는 초기화된 anyNum이라는 변수를 JSX 코드에 어떻게 포함시키는 지 보여준다. {anyNum}

 

리렌더링(rerendering)예시 코드 (별로 안좋은 코드ver)

-어떻게 작동하는 지를 보여주기 위한 코드이다. 해당 방법은 차후 코드를 작성할 때 적용할게 아니라 작동원리만 파악하고 넘어가자.

<body>
    <div id="root"></div>
  </body>
  <!-- react and reactDOM -->
  <script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
  <script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
  <!-- Load Babel -->
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script type="text/babel">
    const root = document.getElementById("root");
    let counter = 0;
    //카운트를 올려주는 기능 - countUP()
    function render() {
      ReactDOM.render(<Container />, root);
    }
    function countUp() {
      counter = counter + 1;
      render();
    }
    const Container = () => (
      //React Element를 함수 내에 담으면 원하는 만큼 사용할 수 있게 된다.
      //함수가 리액트 엘리먼트를 리턴해주기 때문에 코드를 재사용할 수 있다. 컴포넌트 재사용
      //변수를 JSX에 전달하는 방법 -> {변수명}

      <div>
        <h3>Total clicks : {counter}</h3>
        <button onClick={countUp}>Click me!</button>
      </div>
    );
    render();
  </script>
  • 위의 코드는 리렌더링을 하는 예시 코드이다. 리렌더링이 필요한 이유는 countUP함수를 통해 데이터의 값이 변할 때, 업데이트된 데이터의 값이 UI에 반영되지 않기 때문이다. 작동방식을 보면 처음 화면이 로딩됐을 때, 
ReactDOM.render(<Container />, root);
  • 해당 코드만 직접실행되고 나머지는 그렇지 않다. 즉, 화면상(UI)의 값은 실제로 내부 데이터가 이벤트를 통해 변경된다 해도 렌더가 되지 않아서 표기가 되지 않는다는 말이다. * counter 이라는 변수를 따로 만들어뒀으므로 확인을 위해서 콘솔에 counter를 하면 값이 변하는 것을 확인할 수 있다.

즉, 우리는 리렌더링을 통해 변경(업데이트)된 데이터 값을 화면(UI)에도 업데이트하여 표시해줘야 한다. 데이터가 바뀔 때마다 Container를 리렌더링해주는 작업이 필요함 그렇기 때문에 render를 함수로 따로 빼고 counterUP함수가 실행될 때, 데이터의 값이 변하면 이 값이 화면에서도 같이 업데이트 될 수 있도록 render함수를 내부 코드에 써준다. -> 이렇게 되면 값이 변할때마다 수동으로 렌더를 해줘야하는 불편함이 생긴다.

-> 참고로 우리가 리렌더링을 하면 해당 컴포넌트도 바뀐 데이터를 가지고 재생성됨


 

리렌더링(rerendering)예시 코드 (good ver)

-우리가 여기서 사용하는 함수는 React.useState(); 이다.

  • React.useState(0) // [0,f] 배열을 반환 , ()에 아무 값도 입력하지않으면 [undefined, f] 반환
  • 반환값인 배열의 첫번째 요소는 초기값이고, 두번째 요소는 그 값을 바꾸는 함수이다
  • 우리한테 counter라는 data를 주고, 그 counter 값을 바꿀 수 있는 함수(f)를 주고있다.

※useState()를 사용한 변수 선언 위치는 보다시피 내부코드의 return 위에 작성해준다. 

  • 기존 const App =() =>() arrow function형식보단 function App() { return (JSX코드) }를 사용하는 것이  코드작성에 있어서 편할 것이다. 
function App() {
      const data = React.useState(0);
      console.log(data);
      return (
        <div>
          <h3>Total clicks : 0</h3>
          <button>Click me!</button>
        </div>
      );
    }

    ReactDOM.render(<App />, root);

보다시피 useState()는 배열을 반환하고 있기 때문에 컴포넌트에 변수를 연결한다면(JSX 코드에 넣는다면) {data[0]}의 형식으로 써야 한다. 정상작동하는 코드이지만 좀 더 간결하게 코드를 짤 수 있는 방법이 있다. -> 배열에서 요소들을 꺼내서 이름을 부여하는 방법을 선행하고 적용해보자. 

 

배열에서 요소들을 꺼내서 이름을 부여하는 방법 

const food = ["potato", "tomato"]; //배열생성
const [myFavOne, myFavTwo] = food; //원소에 이름부여
console.log(myFavOne); // 결과: potato

▶예시 코드에 적용하기

function App() {
      const [counter, setCounter] = React.useState(0);
      const onClick = () => {
        //어떤 값을 부여하던 modifier 함수는 그 값으로 업데이트하고 내부적으로 리렌더링을 일으킨다.
        setCounter(counter + 1);
      };
      //[0,f] 배열을 반환하는데
      //배열의 첫번째 요소는 초기값이고, 두번째 요소는 그 값을 바꾸는 함수이다.
      //우리한테 counter라는 data를 주고, 그 counter 값을 바꿀 수 있는 함수를 주고있다.
      return (
        <div>
          <h3>Total clicks : {counter}</h3>
          <button onClick={onClick}>Click me!</button>
        </div>
      );
    }

 

const [counter, setCounter] = React.useState(0);에서 0으로 할당된 초기값에 counter이라는 이름을 주고 그 값을 바꾸는 함수에는 setCounter으로 했다.

  • useState의 두번째 인자는 입력받은 값을 변경해주고 자동으로 렌더링해주는 함수이다. modifier라고 부르며 기본적으로 앞의 데이터명에 "set데이터명"으로 작명된다. (위의 코드에서는 counter, setCounter 로 초기값과 함수가 작명되어있음)
  • onClick함수는 우리가 클릭이벤트를 발생시켰을 때 값을 변경하고 렌더링하는 작업을 한다. 정확히 말하면 modifier 함수인 setCounter가 인자로 counter(초기값)+1를 받아서 그 값을 업데이트하고 리렌더링을 자동으로 처리해주면서 화면에도 업데이트하게 된다. 
  • 참고로 React.useState(초기값)을 써주는게 좋다 빈공간으로 할 경우, undefined 가 반환되므로 NaN 에러발생(맞음, 내가 까먹고 안써서 NaN뜸..)

해당 코드와 안좋은 코드를 비교해보면 얼마나 간단하게 리렌더링을 할 수 있고 코드가 간결해지는 지 알 수 있다. 

가장 큰 차이점이라 하면 수동적으로 일일이 리렌더링하는 것과 자동으로 값이 업데이트될 때 내부적으로 리렌더링해주는 것이라고 볼 수 있겠다.

 

 

댓글