[React] State & useState

DongHyeon Jung·2022년 9월 21일
0

React

목록 보기
5/15
post-thumbnail

State

state는 컴포넌트 내부에서 읽고 업데이트 할 수 있는 값이다
[ 초깃값을 설정-> 렌더링 -> 업데이트 ] 이런 과정으로 이루어진다

const root = document.getElementById('root');
    let counter = 0;
    function countUp() {
      counter += 1;
    }
    const Container = () => (
      <div>
        <h3>Total click: {counter}</h3>
        <button onClick={countUp}>click</button>
      </div>
    );

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

버튼을 클릭해도 count는 증가하지 않는다
→ why? 컴포넌트를 한번만 렌더링 되고 있기 때문이다.

UI 가 업데이트 되지 않았기 때문에 화면에 나타나지 않지만, 이벤트 리스너는 동작하는 중이다.
그렇다면 어떻게 UI를 업데이트 하는 코드를 작성하는가??

<Sol 1 🤔>

값이 바뀔때마다 랜더링하는 함수를 만들어준다


const countUp = () => {
      counter += 1;
      render();
    }
    const render = () => {
      ReactDOM.render(<Container />, root);
    }
    const Container = () => (
      <div>
        <h3>Total click: {counter}</h3> 
        <button onClick={countUp}>click</button>
      </div>
    );
    render() // 렌더링해준다

하지만 최선의 방법은 아니다. → render()함수를 호출하는 것을 잊으면 안되기 때문이다.

<Sol 2 😃>

useState() 를 사용하자

function App() {
    let [counter, setCounter] = React.useState(0);
   
    const onClick = () => {
	    setCounter(counter + 1); // 자동으로 변수에 1더해서 리렌더링해줌
    };
    return(
        <div>
          <h3>Total click: {counter}</h3> // 변수를 컴포넌트에 연결
          <button onClick={onClick}>click</button>
	    </div>
    )
}

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

setCounter함수를 이용해서 자동으로 변수에 1씩 더해서 리렌더링을 해준다.
따로 렌더링 함수를 호출할 필요가 없다.
modifier로 state를 변경할 때, 컴포넌트 전체를 재생성함
state가 바뀌면 리렌더링이 일어남

  1. Hook을 이용해서 App이라는 함수형 컴포넌트 안에 state를 추가한다.
  2. useState는 현재 state값과, 이것을 업데이트 하는 함수(modifier)를 쌍으로 제공한다.
  3. 배열 구조 분해를 이용해서, counter라는 변수에 초기 state값 0, setCounter라는 업데이트 함수를 할당한다.
  4. 이후 변수를 컴포넌트에 연결하면, state를 변경할 때마다 리렌더링을 하면서 컴포넌트 전체가 재생성됨.
👉 렌더링을 할때마다 Container컴포넌트를 전체를 생성하는 것이 아니다. 👉 버튼을 클릭할 때마다 바닐라js는 span태그를 포함한 body가 업데이트 된다. 👉 리액트는 div가 업데이트되는 것이 아니라, UI에서 바뀐 부분만 업데이트 해준다. → 다른 부분만 파악한다! → SPA

 주의할 점

const [name,setName] = useState();

function onClick(){
	setName('hi');

	console.log(name); //undefined
}

이때, 왜 name이라는 state값은 바뀌지 않는 것일까?

왜 ‘hi’가 나오지 않는 걸까?

setName을 호출한다고 해서 name이 변경되는 것이 아니다.

import { useState } from "react";

export const Test = () => {
  const [name, setName] = useState<string>();
  const [age, setAge] = useState<number>(0);

  const onClick = () => {
    setName(`hi ${age}`);
    setAge(age + 1);
  }
  return (
    <>
      <button onClick={onClick}>click</button>
    </>
  );
};

클릭을 할 때마다 onClick 함수 안의 state값이 변경되고 있다. → 컴포넌트 전체를 리렌더링한다

이처럼 컴포넌트는 state가 변경될 때마다 전체를 리렌더링하고 있으므로, setState가 호출된 이후 그 값을 사용하게 되는 것이다.

배열을 변수에 담는법 → 배열 구조 분해 문법

하나씩 변수를 설정하지 않아도 된다.

useState로 호출된 state변수들을 다른 변수명으로 할당할 수 있게 한다.

const food= ["apple", "banana"];

const [myFav, mySecFav] = food;

myFav // apple
mySecFav // banana

예를 들어보자

const data = React.useState(34); // [34, ƒ]
const counter = data[0]; // 34
const modifier = data[1];

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

Hook이란?

Hook 은 class를 작성하지 않고도 state와 다른 React의 기능들을 사용할 수 있게 해준다.

  • 최상위에서만 Hook을 호출한다 (반복문 조건문 안에서 실행 x)
  • 함수형 컴포넌트 내에서만 Hook을 호출한다.(일반 js 함수 내에서 호출하지 않는다.)
import React, { useState } from 'react';

function Example() {
  // "count"라는 새 상태 변수를 선언합니다
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

useState가 바로 Hook이다.
Hook을 이용해서 Example이라는 함수 컴포넌트 안에 state를 추가한다.
useState() : 현재의 state값과 이 값을 업데이트 하는 함수를 쌍으로 제공한다.
그리고 인자로 초기 state값을 하나 받고, 카운트가 0으로 시작되도록 0을 초기값으로 넣어준다.

0개의 댓글