Skip to content
On this page

2022년 04월 17일

수정하기
문서 생성 2022-04-17 22:20:10 최근 수정 2022-04-22 21:30:48

📚 오늘 도전하고, 배운 것

React

ref

DOM 요소에 접근해서 작업을 할 수 있게 해주는 것 예를 들면, input에 입력된 값을 상태로 관리할 때 보통 키가 입력될 때마다 상태가 업데이트 되게 된다. 매번 누를 때마다 업데이트되는 것은 좀 과한 느낌이다. 사용자가 입력을 일정 시간 동안 멈췄을 때를 확인하면 좋을 것이다. 그럴 때 "ref"를 사용할 수 있다.

ref 사용하기

ref를 만들고 연결하려는 HTML 요소에 ref props을 추가하면 된다.

const nameInputRef = useRef()
nameInputRef.current // 연결된 실제 DOM을 가리킴
nameInputRef.current.value // 그 값

커스텀 컴포넌트에서 ref 사용하기

다음과 같이 컴포넌트에 ref props을 추가한다.

<Input
ref={countRef}
// ...
/>

해당 컴포넌트에서 컴포넌트를 React.fowardRef의 인자로 설정한다. ref를 두 번째 인자로 받아서 컴포넌트에서 사용 (포워딩된 ref를 컴포넌트 안에 설정하는 것)

import React from 'react'
const Input = React.fowardRef((props, ref) => {
return (
<input ref={ref} />
)
})
export default Input

ref값은 객체, current 라는 property를 가지고 있는데 그 ref가 연결된 실제 값을 갖는다. 실제 DOM 노드가 연결된 것. 그래서 ref를 사용하면 state가 필요 없다. 모든 키 입력을 기록하지 않아도 DOM 요소의 실제 값을 얻을 수 있기 때문에... 만약 값을 읽고 싶기만 하다면, 업데이트 할 계획이 없다면 state가 필요하지 않다! ref가 나을 것

  • ref를 사용한 input 컴포넌트를 제어되지 않는 컴포넌트라 부른다.
    • 왜 제어되지 않을까? 리액트에 의해 제어되지 않는 다는 뜻
  • ref를 추가하지 않고 state를 사용한 것은 리액트에 의해 상태가 제어되므로 제어된 접근 방식이다. React 공식 문서를 보니 Controlled 컴포넌트와 비제어 컴포넌트(uncontrolled component)라고 부른다.

Effect (Side Effect)

리액트의 주된 작업은 화면에 무언가를 가져오는 것이다. 그리고 그 무언가와 상호 작용하게 하는 것인데 그 외에 것을 Side Effect라 칭한다. 예를 들면 http reqeust를 보내는 것이나 브라우저 storage에 뭔가를 저장한다거나 timer를 설정하는 것 등이 있다.

사이드 이펙트는 컴포넌트 함수에 들어가서는 안 된다. 상태가 변경됨에 따라 컴포넌트 함수가 계속 실행될 것인데 그럼 사이드 이펙트도 계속 실행되는 것 -> 버그나 무한 루프가 발생한다. 과도한 http request 가 보내질 수도 있다.

그래서 컴포넌트 함수 외부에 사이드 이펙트를 둬야 한다. 이때 사용할 수 있는 리액트 훅이 있다. useEffect다.

useEffect(() => { ... }, [ dependencies ])

첫 번째 인수는 함수다. 모든 컴포넌트가 평가된 후에 실행되어야 하는 함수다. 이 함수는 지정된 의존성이 변경된 경우에 실행되는데 이 의존성은 두 번째 인수에 지정할 수 있다. (배열)

의존성이 변경될 때마다 첫 번째 인수에 등록된 함수가 실행된다. 컴포넌트가 다시 렌더링될 때는 실행되지 않는 것 -> 사이드 이펙트가 들어가기 적절하다.

폼의 유효성을 확인하고 업데이트하는 것도 사이드 이펙트라 할 수 있음.

종속성으로 추가할 항목과 추가하지 않을 항목에 대하여

useEffect의 함수 내부에서 사용하는 것들을 종속성에 추가해야 하는데 예외가 몇 가지 있다.

  • 상태 업데이트 함수는 추가할 필요가 없다.
    • useState가 반환하는 상태 업데이트 함수는 React 가 해당 함수가 절대 변경되지 않다는 것을 보장하니 종속성에 추가할 필요가 없음
  • 내장 API 함수도 추가할 필요가 없다. (fetch, localStorage...)
    • React의 렌더링 주기와 관련이 없고 변경도 되지 않는다.
  • 변수나 함수
    • 컴포넌트 외부에 정의했을 변수나 함수는 추가할 필요가 없다. 컴포넌트에 영향을 주지 않기 때문이다. 해당 변수나 함수가 변경되더라도 컴포넌트는 재평가 되지 않는다.

Cleanup 함수

디바운스useEffect를 사용해 구현할 수 있다. useEffect 함수가 실행되기 전(처음 실행되는 경우를 제외하고) 클린업 함수가 실행된다.

useEffect(() => {
const timerId = setTimeout(() => {
setFormIsValid(
enteredName.trim().length > 0
)
}, 500)
return () => {
clearTimeout(timerId)
} // cleanup 함수
}, [enteredName])

🤔 학습하면서 궁금하거나 어려웠던 점

🌅 내일은 무엇을?

  • 백준 알고리즘 문제 풀기
  • React 학습

🖋 log

  • 4km 뛰었다.

LINKS TO THIS PAGE