React - useState, useEffect?

김하영·2022년 11월 6일
1

React

목록 보기
1/7
post-thumbnail

useState란?

리액트 컴포넌트에서 동적인 값을 상태(state)라고 부른다.
사용자 인터랙션을 통해 컴포넌트의 상태값이 동적으로 바뀔 경우에는 상태를 관리하는 것이 필요하다.

React Hooks가 나오기 이전에는 상태값을 관리하기 위해 class 기반의 클래스 컴포넌트를 작성해야 했다.
클래스 컴포넌트는 간단한 상태 관리 조차도 함수형 컴포넌트에 비해 복잡하여 유지 보수가 힘들었다.

하지만 리액트 16.8 버전부터 Hooks라는 기능이 도입되면서 함수형 컴포넌트에서도 상태를 관리할 수 있게 되었다.

Hooks중에 하나인 useState()함수형 컴포넌트에서 상태를 관리할 수 있다.

기본 형태

const [state, setState] = useState()

사용 예시

// count.js

import {useState} from 'react'

function App() {
	const [counter, setCounter] = useState(0)
    const onClick = () => {
    	setCounter((current) => current + 1)
    }
    
    return (
    	<div>
        	<h3>Total clicks: {counter}</h3>
            <button onClick={onClick}>Click me</button>
        </div>
    )
}

export default App

1. useState 불러오기

import {useState} from 'react'

2. const [counter, setCounter] = useState(0);

여기서 counter는 변수이고, setCounter는 state 값을 변경시켜주는 함수라고 보면 된다. useState의 변수는 일반 변수와 다르게 값이 변하게 되면 렌더링이 일어난다.
즉, 값이 변하게 되면 연관있는 컴포넌트들이 다시 렌더링이되어 화면이 바뀌게 된다.
useState 괄호 안에는 변수의 초기 값을 설정해 줄 수 있다.

즉,

const [상태 값 저장 변수, 상태 값 갱신 함수] = useState(상태 초기 값)
const onClick = () => {
  setCounter((current) => current + 1)
}

상태 값 갱신 함수인 setCounter는 파라미터로 전달받은 current를 최신 상태로 설정해 준다.

state는 number, string, boolean 등 1개의 자료형을 넣을 수 있지만, 배열이나 객체와 같은 것도 사용할 수 있다.

// ex)


function App() {
  const [toDo, setTodo] = useState("")
  const [toDos, setToDos] = useState([])
  const onChange = (event) => setTodo(event.target.value)
  const onSubmit = (event) => {
    event.preventDefault()
    if (toDo === "") {
      return
    }
    setTodo("")
    setToDos((currentArray) => [toDo, ...currentArray])
  }
  
  return (
  	<div>
      <h1>My To Dos ({toDos.length})</h1>
      <form onSubmit={onSubmit}>
        <input
          value={toDo}
          onChange={onChange}
          type="text"
          placeholder="Write your to do ..."
        />
        <button>Add To Do</button>
      </form>
    </div>
  )
}

useState를 사용할 때 counter = 3 과 같이 직접 수정할 수 없다.
특히, 객체나 배열에 값을 추가하거나 수정할 때는 spread 문법을 사용해야 한다.

setToDos((currentArray) => [toDo, ...currentArray])

* spread 문법

const arr = [1, 2, 3, 4, 5];

const newArr = [...arr, 6, 7]; // [1, 2, 3, 4, 5, 6, 7]

여기서 currentArray가 기존 배열, toDo는 추가할 내용, ...currentArray는 기존 배열의 요소들이다.

이렇게 기존 배열을 복사하여 새로운 배열로 만들어 주는 것을 통해 '불변성'을 지킬 수 있다.
state의 불변성을 지켜줘야만 리액트가 컴포넌트의 상태가 업데이트 되었음을 감지할 수 있고, 필요한 부분만을 리렌더링 할 수 있기 때문이다.

useEffect란?

useEffect함수는 리액트 컴포넌트가 렌더링 될 때마다 특정 작업을 실행할 수 있도록 하는 Hook이다.

useEffect는 리액트 컴포넌트가

  1. mount 되었을 때 (처음 렌더링 되었을 때)
  2. unmount 되었을 때 (컴포넌트가 제거될 때)
  3. update 되었을 때

기본 형태

useEffect(function, deps)
  • function : 수행하고자 하는 작업
  • deps : 검사하고자 하는 특정 값 or 빈 배열

사용 방법

1. useEffect 불러오기

import {useEffect} from 'react'

2. component가 mount 되었을 때

컴포넌트가 화면에 가장 처음 렌더링 될 때 한번만 실행하고 싶을 때는 deps 위치에 빈 배열을 넣는다.

useEffect(() => {
	console.log('처음 렌더링 시 한 번만 실행됨')
}, [])

3. 특정 state가 update 되었을 때

const [counter, setCounter] = useState(0)

useEffect(() => {
	console.log('counter가 변경되었을 때마다')
}, [counter])

특정 조건을 추가해주고 싶다면 if문을 함께 사용 가능하다.

useEffect(() => {
	if (counter > 5) {
		console.log('counter가 5보다 클때 && 변경되었을 때마다')
    }
}, [counter])

4. 컴포넌트가 unmount될 때(사라질 때)

  • cleanup 함수 반환 (return 뒤에 실행되는 함수)
function Hello() {
  useEffect(() => {
    console.log('hi :)')
    return () => console.log('bye :(')
  }, [])

  return <h1>Hello</h1>
}

function App() {
  const [showing, setShowing] = useState(false)
  const onClick = () => setShowing(prev => !prev)

  return (
    <div>
      {showing ? <Hello /> : null}
      <button onClick={onClick}>{showing ? 'hide' : 'show'}			  </button>
    </div>
  );
}

위 코드에서 hi는 Hello 컴포넌트가 생성될 때,
bye는 Hello 컴포넌트가 사라졌을 때 실행된다.

여기까지 useState, useEffect 정리 끝! :)

profile
호기심 많은 프론트엔드 주니어 💡

0개의 댓글