본문 바로가기

FrontEnd/React

React Hooks -useState에 대하여

출처: https://www.youtube.com/watch?v=G3qglTF-fFI&list=PLZ5oZ2KmQEYjwhSxjB_74PoU6pmFzgVMO

useState

function heavyWorkd() {
	// 뭔가 엄청 무거운 작업
}

useState(()=>{}) // 또는 useState(heavyWork)

useState(heavyWork())이 아닌, 위의 예시처럼 콜백 형식으로 무거운 작업을 넣어주면 맨처음 렌더링 될 때 한번에만 불린다.

즉 초기값을 가져올 때 무거운 함수를 가져온다면 콜백 형식으로 넣어주기.

import { useState } from 'react';

const App=()=>{
  const [names, setNames]=useState(['']);
  const [input, setInput]=useState('');
 

  const handleInput=(e)=>{
    setInput(e.target.value);
  }
  const handleUploadInput=()=>{
        /**
     * 위의 handleInput과 같이 state의 상태를 변경하는게 단순히 setInput으로 가능하지만
     * 아래와 같이 전의 상태와 관련된 값을 상태로 주기 위해서 화살표 함수를 사용하고 이때는 반드시 return을 붙여주어야 한다.
     * 그리고 return 되는 내용이 새롭게 갱신될 state의 값이다.
     */

    setNames((previous)=>{return [input, ...previous]})
  }
  console.log(input);//프로그램을 실행해 보면 알겠지만 input창의 onChange속성으로 handleInput이란 함수를 값으로 취했다. 그런데 handleInput함수안에서
  //state를변경하는 setInput함수가 존재한다. 함수형 컴포넌트에서는 state가 변경될때마다 컴포넌트 전체가 재실행 되면서 한글자 입력될 때마다 console.log(input)
  //이 매번 실행되는 것을 확인할 수 있다.
  return (
  <div>
  <input onChange={handleInput}></input>
  <button onClick={handleUploadInput}>Update</button>
  {/* 배열을 대상으로 어떤 행위를 할때 런타임 오류가 난다면 return을 꼭 붙여 볼것. 아래 return이 없어도 컴파일 오류는 생기지 않지만 런타임때 오류남 */}
  {names.map((src, idx)=>{ return <p key={idx}>{src}</p>})}
  </div>
  )
}

export default App;

==============================================================================

위와 같이 완성한후 개선할 것을 살펴보면 state를 변화시키는 함수(set~~)때문에 state가 변경될 때마다 컴포넌트 전체가 리랜더링되는 것을 확인할 수 있다. 만약 컴포넌트 안에 매우 무거운 작업을 하는 함수가 있다면 이는 리랜더링 시마다 그 함수가 매번 재정의 되므로 매우 비효율적이다.

기존에 키보드 하나 누를때마다 setInput이 호출되게 해놓았고 이에 따라 키보드하나 누를 때마다 리랜더링이 된다. 또한 이에따라 리랜더링 될때마다 무거운 함수가 매번 실행된다...

이를 개선하기 위해 맨처음 랜더링 될때만 heavyWork함수를 호출하게 할 수 없을까?

있다!!! 초기값을 넣는 인자 자리에 바로 함수 heavyWork를 넣지 않고 화살표 함수로 아래와 같이 callBack형식을 만들어 주면 된다!!!

화살표 함수와 return으로 함수를 반환하는 콜백함수를 이용한다.