여행가는개발자

React Hooks useRef 본문

React

React Hooks useRef

kimsoonil 2023. 9. 13. 16:14
728x90
반응형

JavaScript 를 사용 할 때에는, 우리가 특정 DOM 을 선택해야 하는 상황에 getElementById, querySelector 같은 DOM Selector 함수를 사용해서 DOM 을 선택합니다.

리액트를 사용하는 프로젝트에서도 가끔씩 DOM 을 직접 선택해야 하는 상황이 발생 할 때도 있습니다. 예를 들어서 특정 엘리먼트의 크기를 가져와야 한다던지, 스크롤바 위치를 가져오거나 설정해야된다던지, 또는 포커스를 설정해줘야된다던지 등 정말 다양한 상황이 있겠죠. 추가적으로 Video.js, JWPlayer 같은 HTML5 Video 관련 라이브러리, 또는 D3, chart.js 같은 그래프 관련 라이브러리 등의 외부 라이브러리를 사용해야 할 때에도 특정 DOM 에다 적용하기 때문에 DOM 을 선택해야 하는 상황이 발생 할 수 있습니다.

그럴 땐, 리액트에서 ref 라는 것을 사용합니다.

 

포커스를 얻기위한 페이지 로딩 입력의 예

FocusInput.js

 

import React, { useEffect, useRef} from 'react'

function FocusInput() {
  const inputRef = useRef<HTMLInputElement>(null)
  useEffect(() => {
    inputRef.current && inputRef.current.focus()
  }, [])

  return (
    <div>
      <input ref={inputRef} type="text" />
    </div>
  )
}

export default FocusInput

App.js

 

import React from 'react'
import './App.css'

import FocusInput from './components/28FocusInput'

const App = () => {
  return (
    <div className="App">
      <FocusInput />
    </div>
  )
}

export default App

TypeScript으로 작성할 때 먼저 제네릭을 선언해야합니다.

const inputRef = useRef<HTMLInputElement>(null)

동시에 사용하는 경우 공백이어야합니다.

inputRef.current && inputRef.current.focus()

ts와 hook의 조합에 대해서는 TypeScript and React: Hooks 문서를 참조하십시오.

useRefRef는 .current속성이 들어오는 매개 변수 (initialValue)로 초기화 된 변수 객체를 반환합니다 . 반환 된 참조 개체는 구성 요소의 전체 수명주기 동안 변경되지 않은 상태로 유지됩니다.

Ref는 렌더링 메서드에서 생성 된 DOM 노드 또는 React 요소에 액세스 할 수있는 방법을 제공합니다.

일반적인 React 데이터 흐름에서 props는 부모 구성 요소가 자식 구성 요소와 상호 작용하는 유일한 방법입니다. 하위 구성 요소를 수정하려면 새 소품으로 다시 렌더링해야합니다. 그러나 경우에 따라 일반적인 데이터 흐름 외부에서 하위 구성 요소를 강제로 수정해야합니다. 수정 된 하위 구성 요소는 React 구성 요소의 인스턴스이거나 DOM 요소 일 수 있습니다. 두 경우 모두 React는 솔루션을 제공합니다.

 

다음은 심판이 적합한 몇 가지 상황입니다.

  • 포커스, 텍스트 선택 또는 미디어 재생을 관리합니다.
  • 강제 애니메이션을 트리거합니다.
  • 타사 DOM 라이브러리를 통합합니다.

선언적 구현을 ​​통해 수행 할 수있는 작업을 수행하기 위해 ref를 사용하지 마십시오. 예를 들어 Dialog 구성 요소에서 open () 및 close () 메서드가 노출되지 않도록하려면 isOpen 속성을 전달하는 것이 좋습니다.

Refs를 과도하게 사용하지 마십시오.

먼저 앱에서 "일이 일어나도록"하기 위해 ref를 사용하는 것을 생각할 수 있습니다. 이 경우 상태 속성을 정렬해야하는 구성 요소 레이어를 신중하게 고려하십시오. 일반적으로 상위 구성 요소 수준이이 상태를 소유하도록하는 것이 더 적절하다는 것을 이해하고 싶을 것입니다. 더 많은 예를 보려면 상태 프로모션을 참조하세요.

refs 및 Dom에 대한 자세한 내용은 React 공식 웹 사이트 Refs and the DOM을 참조하십시오.

다른 시나리오에서 useRef를 사용하는 방법에 대해 알아 보겠습니다.

중지 할 수있는 타이머의 예

요구 사항은 페이지에 1 초마다 자동으로 증가하는 타이머가 있고 버튼이 있으며, 클릭하면 타이머가 중지됩니다. 먼저 클래스 구성 요소를 사용하여이 요구 사항을 완료합니다.

Class 구성요소

ClassTimer.js

import React, { Component } from 'react'

export default class ClassTimer extends Component<{}, { timer: number }> {
  interval!: number
  constructor(props: Readonly<{}>) {
    super(props)
    this.state = {
      timer: 0
    }
  }

  componentDidMount() {
    this.interval = window.setInterval(() => {
      this.setState(prevState => ({
        timer: prevState.timer + 1
      }))
    }, 1000)
  }

  componentWillUnmount() {
    clearInterval(this.interval)
  }

  render() {
    return (
      <div>
        Timer - {this.state.timer}
        <br/>
        <button
          onClick={() => {
            clearInterval(this.interval)
          }}
        >Clear Timer</button>
      </div>
    )
  }
}

App.js

import React from 'react'
import './App.css'

import ClassTimer from './components/29ClassTimer'

const App = () => {
  return (
    <div className="App">
      <ClassTimer />
    </div>
  )
}

export default App

Function 구성요소

HookTimer.js

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

function HookTimer() {
  const [timer, setTimer] = useState(0)

  //  @ts-ignore
  const intervalRef = useRef(null) as { current: number }

  useEffect(() => {
    intervalRef.current = window.setInterval(() => {
      setTimer(pre => pre + 1)
    }, 1000)
    return () => {
      clearInterval(intervalRef.current)
    }
  }, [])
  return (
    <div>
      HookTimer - {timer}
      <br />
      <button
        onClick={() => {
          clearInterval(intervalRef.current)
        }}
      >Clear Hook Timer</button>
    </div>
  )
}

export default HookTimer

App.js

import React from 'react'
import './App.css'

import ClassTimer from './components/29ClassTimer'
import HookTimer from './components/29HookTimer'

const App = () => {
  return (
    <div className="App">
      <ClassTimer />
      <hr />
      <HookTimer />
    </div>
  )
}

export default App

728x90
반응형

'React' 카테고리의 다른 글

React social login - Kakao  (0) 2023.09.13
React social login - Facebook  (0) 2023.09.13
Redux  (0) 2023.09.13
React Hooks useState  (0) 2023.09.13
React Hooks useState  (0) 2023.09.13