React useState

 React useState




리액트로 개발 할 때 함수형 컴포넌트를 사용하면 React Hook을 사용 할 줄 알아야 합니다.

그중에 useState는 리액트의 가장 기본적인 Hook입니다.

state는 컴포넌트의 상태라고 합니다.

이 useState 없이는 값을 바꿀 수 없습니다.

 
const [상태, set상태] = useState(초기값)

배열에 첫번째 인덱스는 변수명을 넣고 두번째 인덱스에는 이 변수를 변경할 수 있는 함수를 넣는데 이 함수는 set함수라고 부릅니다.

useState를 쓰기 위해서는 컴포넌트 바깥에서 import를 해와야 쓸 수 있습니다.


자동완성 기능을 사용하면 빠르게 import를 할 수 있습니다. 

변수를 html 태그에 포함 시킬 때에는 html 코드에서 중괄호 {}를 넣고 그 사이에 변수명을 입력합니다. 그러면 초기값을 브라우저에 띄울 수 있습니다.


import { useState } from "react";
import "./App.css";

function App() {
  const [plus, setPlus] = useState(0);

  const addFn = () => {
    setPlus(plus + 1);
  };

  return (
    <div className="App">
      <span>수량: {plus}</span>
      <button onClick={addFn}>+</button>
    </div>
  );
}

export default App;

setPlus는 상태값을 바꿔주는 set함수 입니다.

자바스크립트에서는 addEventListener를 이용해서 이벤트를 줄 수 있었지만 리액트에서는 좀 다릅니다. onClick 속성을 사용해서 함수를 넣어야 합니다. 위의 코드에서는 addFn이라는 함수를 가르키고 있지만 콜백함수를 넣을 수도 있습니다.


<button
        onClick={() => {
          setPlus(plus + 1);
        }}
      >
        +
</button>

간단한 코드는 콜백함수를 이용할 수 있지만 코드의 가독성을 위한다면 첫번째 코드를 이용해서 하면 좋을 것 같습니다.

위의 코드를 입력하고 브라우저로 돌아가서 버튼을 클릭해보면 0이 1씩 증가하는 것을 볼 수 있습니다.

이제 useState를 이용해서 학생의 이름을 추가하는 코드를 만들어보겠습니다.

학생의 이름을 쓸 input 태그와 이름을 쓰고 upload할 button 태그를 만듭니다.

그리고 학생의 이름을 저장할 state를 만들어야 합니다.


import { useState } from "react";
import "./App.css";

function App() {
  const [names, setName] = useState(["홍길동", "김철수"]);
  const [input, setInput] = useState("");

  console.log(names);

  const inputHandler = (e) => {
    //e.target.value를 쓰면 내가 타이핑한 값이 나온다.
    setInput(e.target.value);
  };

  const addFn = () => {
    setName((prev) => {
      return [input, ...prev];
    });
  };
  return (
    <div className="App">
      <input type="text" onChange={inputHandler}></input>
      <button onClick={addFn}>Upload</button>
      {names.map((data, idx) => {
        return <p key={idx}>{data}</p>;
      })}
    </div>
  );
}

export default App;

set함수에서 콜백함수를 이용하면 이전 state를 가지고 옵니다.

prev를 console.log으로 찍고 input에 이영희를 입력하면 console.log에 이전 state인 홍길동, 김철수가 나옵니다. 그리고 김민수를 입력하면 console.log에는 이전 state인 이영희, 홍길동, 김철수가 나오게 됩니다.

학생의 이름을 추가하는 코드는 완성 되었지만 이 코드는 업데이트 될 때마다 컴포넌트가 렌더링이 되어버립니다. 여기서 말하는 업데이트란 단순히 업로드 버튼을 눌렀을 때가 아니라 input에 글자 하나하나 타이핑 할 때마다도 업데이트에 속합니다. 이렇게 초기값에 무거운 작업 코드가 있다면 성능에 좋지 않습니다.

이럴 때에 useState인자에 값을 바로 넣어주는것이 아니라 콜백함수를 쓰고 그 안에서 초기값을 지정해주면 업데이트가 되어도 최초 한번만 렌더링이 됩니다.


import { useState } from "react";
import "./App.css";

const val = () => {
  console.log("무거운 작업");
  return ["홍길동", "김철수"];
};

function App() {
  const [names, setName] = useState(() => {
    return val();
  });
  const [input, setInput] = useState("");

  const inputHandler = (e) => {
    //e.target.value를 쓰면 내가 타이핑한 값이 나온다.
    setInput(e.target.value);
  };

  const addFn = () => {
    setName((prev) => {
      // console.log(prev);
      return [input, ...prev];
    });
  };
  return (
    <div className="App">
      <input type="text" onChange={inputHandler}></input>
      <button onClick={addFn}>Upload</button>
      {names.map((data, idx) => {
        return <p key={idx}>{data}</p>;
      })}
    </div>
  );
}

export default App;

완성된 코드는 위와 같습니다.

useState를 쓸 줄 안다고 생각했지만 생각보다 더 자세한 기능이 있었습니다.

댓글

이 블로그의 인기 게시물

[정보처리기사] OSI 7계층 정리

블로그스팟 상위노출 시작하기

데이터베이스 데이터 정의어(DDL), 자료형(데이터 타입)