React useState , 내 상태도 바꿔봐

수딩·2022년 6월 16일
0
post-thumbnail

useState

react 에서 State 는 컴포넌트의 상태를 말한다.

 const [state, setState] = useState(초기값);

state 는 현재 상태값, setState 는 변경해주고 싶은 값이다.

예를 들어 시계라는 컴포넌트가 있다면, state 는 time 라고 볼 수 있는데
useState 는 이 상태를 업데이트 해주는 도구를 제공해준다!

import { useState } from "react";

function App() {
  const [time, setTime] = useState(1);
  return (
    <div>
      <span>현재 시각 : {time}</span>
      <button>Update</button>
    </div>
  );
}

export default App;

import { useState } from "react"; 로 import 하고고
const [time, setTime] = useState(1); 로 useState를 사용했다.

지금 이 코드에서는 클릭했을 때 time + 1 을 해주고 싶음!
그래서 현재시각을 {time}함수로 만들어줬고
handleClick 함수를 만들어서 클릭했을 때 time+1 이 되게끔 했다.

function App() {
  const [time, setTime] = useState(1);
  
  const handleClick = () => {
    let newTime;
    if (time >= 12) {
      newTime = 1;
    } else {
      newTime = time + 1;
    }
    setTime(newTime);
  };
  
  return (
    <div>
      <span>현재 시각 : {time}</span>
      <button onclick={hadleClick}>Update</button>
    </div>
  );
}

time 에는 업데이트 된 state 가 되는 것.


useState 활용해서 input 값 업데이트 해보기


input 에 값을 넣으면 그 값이 저장되어 아래에 적히게끔 만들어 보자 .
우선 기본 코드는

import { useState } from "react";

function App() {
  return (
    <div>
      <input type="text" />
      <button>Upload</button>
    </div>
  );
}

export default App;

이제 이 코드에서 useState 를 사용해주기 위해
map 으로

를 return 해줄 것
map을 쓰기 위해서는 key 와 value 값이 있어야 한다.

 {names.map((name, index) => {
        return <p key={index}>{name}</p>;
      })}

여기서 이제 input 안에 무슨 값이 있는지 트래킹해주는 state 함수가 있었으면 좋겠다!

빈 문자열을 초기값으로,

  const [input, setInput] = useState('');

useState 를 생성해주고
input 값의 value 에 state 로 만들어줌!

이제 사용자가 input 값을 넣을 때
입력 할때마다 핸들링 할 수 있는 함수를 만들어 주자 !

 const handleInputChange = (e) => {
    setInput(e.target.value);
  }
 
<input type="text" value={input} onChange={handleInputChange}/>

을 추가해주고 콘솔창으로 확인해보면

인풋값에 입력한대로 콘솔에 찍히고 있다!

자 이제 버튼을 클릭하면 상태를 업로드해주는 handleUpload 를 해주는 함수를 만들어 주자

const handleUpload = () => {
    setNames(() => {
      return()
    })
  }

handleUpload 에는 위에서 작성해준 setNames 를 불러옴!
setNames()안의 콜백의 인자에는 업데이트하기 이전 상태를 가지고 있게, return 안에 업데이트 할 상태를 출력하게 한다.
콜백 인자에는 prevState 넣어주면 되는데,
prevState 는 배열로 들어있기 때문에 return [input, ...prevState]; 으로 작성해주면 된다.

const handleUpload = () => {
    setNames((prevState) => {
      console.log("이전 state:", prevState);
      return [input, ...prevState];
    });
  };

콘솔로 지금 상태를 확인해보면 이렇게 이전의 state 가 잘 출력됨을 볼 수 있다.

지금까지의 코드를 보면

import { useState } from "react";

function App() {
  const [names, setNames] = useState(["수콩", "콩콩"]);
  const [input, setInput] = useState("");

  const handleInputChange = (e) => {
    setInput(e.target.value);
  };

  const handleUpload = () => {
    setNames((prevState) => {
      return [input, ...prevState];
    });
  };

  return (
    <div>
      <input type="text" value={input} onChange={handleInputChange} />
      <button onClick={handleUpload}>Upload</button>
      {names.map((name, index) => {
        return <p key={index}>{name}</p>;
      })}
    </div>
  );
}

export default App;

근데 잠깐만요 !~!~!

지금 계속 이전의 값을 불러오는데 만약 이게 엄청 무거운 값이라면 성능이 너무 저하되는 것 아닌지..?
그래서
지금의 코드는 너무 비효율적이다!! 이걸 개선하기 위해서

const heavyWork = () => {
  console.log("엄청 무거운 작업");
  return ["수콩", "콩콩"];
};

한다고 생각하고! heavyWork 라는 함수를 만들어주자. 그러면 이걸 어떻게 쓰냐 ?

 const [names, setNames] = useState(() => {
    return heavyWork();
  });

처음에 렌더링이 될때만 이 함수를 사용하고 싶기 때문에 초기값을 넣는 인자에 바로 값을 너어주는 것이 아니라, 콜백을 넣어준다!
그리고 콜백형태로 원하는 값(초기값)만을 리턴 해주는 것 .

이제 input 을 추가했을 때 '엄청 무거운 작업' 인 초기값이 안드는 것을 볼 수 있다!

결론적으로! 초기값을 넣어줄때 초기값이 무거운 작업이라면, 따로 함수를 만들어서 콜백을 통해 처음에만 렌더링 되게 해줄 수 있다 .

최종 코드

import { useState } from "react";

const heavyWork = () => {
  console.log("엄청 무거운 작업");
  return ["수콩", "콩콩"];
};

function App() {
  const [names, setNames] = useState(() => {
    return heavyWork();
  });

  const [input, setInput] = useState("");

  const handleInputChange = (e) => {
    setInput(e.target.value);
  };

  const handleUpload = () => {
    setNames((prevState) => {
      console.log("이전 state:", prevState);
      return [input, ...prevState];
    });
  };

  return (
    <div>
      <input type="text" value={input} onChange={handleInputChange} />
      <button onClick={handleUpload}>Upload</button>
      {names.map((name, index) => {
        return <p key={index}>{name}</p>;
      })}
    </div>
  );
}

export default App;

참고 : 유튜브 별코딩 React-Hooks에 취한다

profile
Front-End Developer ✨

0개의 댓글