본문 바로가기
공부/React.js

[React] Hook (feat. useState, useEffect)

by Mr. Green 2023. 2. 17.

 안녕하세요. 이번에 볼거는 react의 또다른 핵심 기능인 Hook이라는 것입니다. (2023.05.10 글 업데이트)

 차례

 0. Hook

 1. useState

 1-1. onClick

 1-2. 배열

 2. useEffect

 2-1. title

 

 0. Hook

 hook은 갈고리라는 뜻으로, 데이터를 갈고리로 낚아채 다시 업데이트 시키는 역할을 하게 됩니다. (전문용어로는 상태 로직을 추상화한다고 하는데, 솔직히 이해는 못했습니당.)

 따라서 변수를 업데이트하거나 이벤트를 반복해야 할 때, 즉, SNS 처럼 동적인 페이지를 만들기 위해 사용하게 됩니다.

 종류로는 useState, useEffect, useRef 등이 있습니다.

 

 사용하기 위해선 맨 윗줄에 모듈을 호출해야 합니다.

import React, {useState, useEffect, ...} from 'react'

 

 1. useState

 변수를 다루는 useState입니다. 그런데 쓰는 방식이 독특합니다.

 

let [a, b] = useState(0)

 배열로 2개의 원소를 받고, useState() 괄호 안에 기초값을 넣습니다.

 0번 원소는 괄호 안의 기초값을 받아 넣습니다. b는 a를 다루는 함수가 됩니다. (b의 이름을 헷갈리지 않게 잘 정해줘야 합니다.)

중간 거는 이전에 했던거니 생략

 실행하면 버튼에 0이 표시되고 버튼을 누르면 함수가 작동하게 만들었습니다.

 함수를 작동시켜 페이지에 값을 표시하기 위해선 새로고침을 하거나 innerHTML 등을 사용해야 하지만, useState를 사용하면 함수 한 줄 만으로도 변경된 값이 페이지에 갱신됩니다.

 즉, 버튼을 누르면 숫자가 하나씩 늘어납니다.

 

 b 함수는 다른 함수로 만들어서 onClick 등에 사용할 수 있습니다.

 다음과 같이 활용할 수 있습니다.

 +를 누르면 증가하고, -를 누르면 감소합니다.

 

 1-1. onClick

 그런데 onclick에서 쓰인 것들의 차이를 보셨나요?

 위에서 보신 것처럼 onclick 등 이벤트를 다루는 html 태그에서 함수를 쓰는 방식은 다음과 같이 두 가지가 있습니다.

 

onClick={함수}
onClick={() => {함수(값)}}

 

 첫 번째는 함수만 쓰면 될 때 쓰는 방식이고, 두 번째는 값을 넣어야 하는 함수를 써야 할 때 사용합니다. 물론 두 번째 방식으로도 그냥 값 없이 쓸 수 있습니다.

 

 1-2. 배열

 useState로 배열을 다룰 수 있습니다. 근데 선언까지는 같지만, 쓰는 방법이 조금 다릅니다.

 

let [a, b] = useState([1, 2, 3])
let [a, b] = useState(['banana', 'apple', 'grape'])

 

 배열에서 b(a.push('어쩌구')) 등 처리를 하면 a를 업데이트 할 수 있지만, 원하는 결과는 나오지 않습니다. 이유는 메모리에서 배열을 다루는 방식 때문인데, 배열을 제대로 다루기 위해선 'spread' 문법이란 걸 사용해야 합니다.

 

let a_ = [...a]

b(a_.push('어쩌구'))

 

 첫 줄에 ...이 spread 문법이며, 괄호 안의 내용물만 가져와 복제품을 만드는 것이라 생각하면 될 거 같습니다. 특히 변수로 만들고, 가공을 하면 원조 데이터에 영향을 주는데, spread 문법을 사용하면 원본 데이터는 보존됩니다.

 

더보기

 메모리에 배열을 저장할 때, 배열의 내용을 나란히 배열한 후, 그 첫 번째 원소의 위치 주소만 변수에 담습니다. (C언어에서 포인터를 배울 때 알 수 있습니다.)

 이 변수를 사용하게 되면 위치 주소에 연결된 배열에 영향을 주기 때문에 원본 데이터를 훼손합니다.

a = [1, 2, 3]
b = a

b.push(4)
console.log(a)

 위를 실행하면 a는 [1, 2, 3, 4]가 됩니다.

 이때, spread를 사용하면 원본 데이터의 위치 주소를 따라 데이터를 복제한 후 다른 주소에 새 배열을 만듭니다.

a = [1, 2, 3]
b = [...a]

 이걸로 수정하면 a와 b는 달라질 겁니다.

 

 이는 제가 이해한 대로 쓴 것이라 엄밀히 따지고 보면 틀릴 수 있으니, 참고로만 봐주시길 바랍니다.

 

 2. useEffect

 useEffect는 페이지가 렌더링 된 후 코드를 실행시키는 역할을 합니다. (참고)

 보통 이벤트를 넣어야할 때 이벤트가 페이지에 바로바로 작용해야할 때 사용합니다.

 

 2-1. title

 react에선 html로 title을 바꿀 방법이 없는데, useEffect를 이용하면 쉽게 만들 수 있습니다.

 

function titler(){
	const htmlTitle = document.querySelector('title')
	htmlTitle.innerHTML = '대충 제목'
}
function titler(){
	document.title = `대충 제목`
}

 두 가지 방식으로 title을 바꿀 수 있습니다.

 

useEffect(() => 
	document.title = `대충 제목`
)

useEffect(titler)

 마찬가지로 useEffect 안에 함수를 쓰는 방식이 두 가지입니다. (javascript 처럼 변수를 섞어 쓸 수 있습니다.)

 

2-1. setInterval

 일정 시간마다 코드를 실행시키는 방법입니다.

 기본 문구는 다음과 같습니다.

setInterval(함수, 시간)

 함수는 화살표 함수도 가능하고, 시간은 ms( = 0.001초) 단위입니다.

 

 useEffect 안에 넣을 땐 위와 같습니다.

let [dodo, dodos] = useState(100)

useEffect(() => {
	setInterval(() => dodos(dodo-1), 1000)
    })

return (
<div>{dodo}</div>
)

 useState와 연계해 화면에 표시되도록 예제를 만들었습니다. 1초마다 100부터 1씩 줄어듭니다.

 근데 위처럼 쓰면 숫자가 작아질수록 100에서 n까지 줄어드는 과정이 보입니다. 따라서 useEffect 안에 다음 문구를 추가해주면 됩니다.

useEffect(() => {
	const timer = setInterval(() => dodos(dodo - 1), 1000)

	return () => clearInterval(timer)
    }, [dodo, dodos])

 clearInterval은 입력된 인자를 중단시킬 때 사용합니다. 즉, return을 통해 반복이 끝난 결과물을 반환하게 됩니다.

 마지막 배열이 추가되었는데, 이는 안에서 변화가 발생하는 변수/함수를 넣어줍니다. (이렇게 이해했는데, 아닐 수도 있어서 잘 찾아보셔야 할거 같습니다.)

 

 

 나머지도 공부하는 데로 써보려합니다.

 감사합니다.