React : useRef 후크와 함께 Ref 사용

예제 사용 사례와 함께 후크를 사용하여 React에서 Refs 구현

Refs : 상태가없는 React의 구성 요소 변이

React의 Ref는 컴포넌트의 라이프 사이클 전체에 걸쳐 가변 값을 저장하는 수단을 제공하며 컴포넌트를 다시 렌더링 할 필요없이 DOM과 상호 작용하는 데 자주 사용됩니다. 즉, Refs로 요소를 업데이트하기 위해 상태 관리에 의존 할 필요가 없습니다. 이것은 몇 가지 선택된 사용 사례에서 매우 유용하지만 상태 관리 또는 라이프 사이클 방법 통합 대신 사용할 때 안티 패턴으로도 간주됩니다.

그러나 이제 React 후크가 프레임 워크에 통합되었으므로 클래스 구성 요소와 수명주기 메서드를 이제 React 후크로 대체 할 수 있습니다.

useRef사용하는 용액은 기능 컴포넌트 내에 심판 반응으로 후크 구현되었다. 우리는이 글에서 함께 잘 작동하는 다른 것들과 함께이 후크를 탐색 할 것입니다. 더 구체적으로, 우리는 :

  • 커버 방법을 사용하는 useRef기능적 구성 요소와 함께 후크를, 일반적으로 사용되는 후크의 몇 가지 사용 사례를 포함 useEffect하고useLayoutEffect
  • useRef동시 React와 함께 올바르게 사용할 수있는 방법
  • useRef데모 구성 요소 사용 사례 살펴보기

프로젝트를 기능적 구성 요소로만 이동할 가치가 있습니까?

기능적 구성 요소가 속도 및 상용구 최적화를 제공하는 경우 클래스 구성 요소는 검증 된 구성 요소 수명주기 방법과 잘 알려진 구조를 제공합니다 ( this클래스 속성 사용 등).

코드 적합성을 높이기 위해 개발자는 일반적으로 프로젝트에 대한 클래스 구성 요소 전용 접근 방식 또는 기능 구성 요소 전용 접근 방식을 선택합니다. 저는 개인적으로 기본 선택으로 기능적 구성 요소를 만들고 수명주기 메서드, 많은 클래스 속성 등을 명시 적으로 정의하려는 경우와 같이 의미가있는 클래스 구성 요소로 대체하는 것을 선택합니다.

내 경험상 Typescript는 또한 클래스 구성 요소를 함수 구성 요소보다 훨씬 더 보완하는 것처럼 보이며 유형을 클래스 자체에 연결할 수있을뿐만 아니라 속성 및 메서드도 가능합니다. 클래스는 좀 더 자세한 구조를 가지고 있습니다.

어쨌든 React Ref는 클래스와 기능 구성 요소 모두에서 활용 될 수 있습니다. useRef후크로 ref를 활용하는 방법을 살펴 보겠습니다 .

또한 여기에 기본 클래스 구현을 중심으로 React Refs에 대한 소개를 게시했습니다 . 독자가 ref의 개념을 처음 접하는 경우 읽을 가치가 있습니다.

useRef 후크 구현

기능 컴포넌트 Ref의 구현은라는 후크를 통해 이루어졌습니다 useRef. 이것이 어떻게 통합되는지 살펴본 다음 그 특성과 사용시기를 살펴 보겠습니다.

컴포넌트 내에서 Ref를 정의 할 수 있습니다.

import React, { useRef } from 'react';
...
const refContainer = useRef(initialValue);

Refs의 기본 클래스 구현과 일치하도록 참조 된 객체 자체는 current이 컨테이너 변수 의 속성에 저장됩니다 . 이 current속성 에 대한 두 가지 주요 사실 :

  • 속성은 변경 가능합니다.
  • 구성 요소 수명주기 동안 언제든지 변경 될 수 있습니다.

또한 initialValue위에서 전달한 인수를 사용하여 current기본값 으로 초기화 할 수 있습니다 . 이 값은 실제로 DOM에서 요소를 참조하거나 임의의 값을 할당 할 때까지 자리 표시 자 역할을합니다.

이벤트 참조는 일반적으로 DOM 요소를 참조하는 데 사용되지만 기본 유형과 객체를 저장할 수도 있습니다. 두 경우의 예를 다룰 것입니다.

의 초기 값을 전달하는 것도 완벽하게 합법적입니다 null.

// initialising an empty reference
const myRef = useRef(null);

// see for yourself what the Ref is actually referencing
console.log(refContainer.current);

// referencing a `button` element
...
render() {
  return(
    <button ref={refContainer}>
      Press Me
    </button>
  );
}

버튼을 참조하는 경우 refContainer.current해당 <button />DOM 요소를 가리키면 버튼의 포커스 / 흐림과 같은 컨트롤과 스타일 및 이벤트 핸들러 ( onClick예 : 클릭 이벤트 트리거)에 액세스 할 수 있습니다.

블러 링은 활성 요소를 비활성화하는 데 사용되는 용어입니다. 텍스트 상자가 활성화 된 경우 (텍스트 입력을 위해 커서가 내부에서 깜박임) 해당 요소 외부를 클릭하거나 Refs와 같은 기능을 프로그래밍 방식으로 사용하여 해당 요소를 흐리게 처리하여 선택 취소 할 수 있습니다.

refs로 버튼 상태를 관리하는 것이 좋습니다.

useRef버튼 의 첫 번째 유효한 사용 사례를 살펴 보겠습니다 .

버튼은와 함께 사용하기에 좋은 사용 사례입니다. useRef따라서 버튼의 상태 (구성 요소 상태와 혼동하지 말 것)를 조작 할 때 전체 구성 요소를 다시 렌더링 할 필요가 없습니다.

실제 시나리오를 생각해 봅시다. 양식이 완료되었으며 기본 비활성화 상태에서 제출 버튼을 활성화해야 할 수 있습니다. 이 작업을 수행하기 위해 전체 양식을 다시 렌더링하려면 다음을 수행해야합니다.

  • 내 현재 양식 값을 모두 상태로 저장
  • 현재 값으로 전체 양식을 다시 렌더링하십시오.
  • 유효성 검사 메시지 및 시각적 표시기와 같이 하위 구성 요소에있을 수있는 다른 모든 상태 유지
  • 발생할 수있는 전환 또는 애니메이션 재설정

refContainer.current.setAttribute("disabled", true);
// or 
refContainer.current.removeAttribute("disabled");

커밋 구성 요소 단계에서 useRef를 올바르게 구현

를 구현하는 방법을 완전히 이해하려면 useRefReact 컴포넌트 실행의 두 단계와 이것이 React refs와 함께 작동하는 방법을 이해해야합니다.

Ref는 기능적 구성 요소의 기본 블록에서 정의 할 수 있지만 이벤트 리스너 또는 타이머와 같은 Ref와 관련된 모든 부작용은 구성 요소의 커밋 단계 에서 정의되어야합니다 . DOM이 발생합니다. 좀 더 자세히 살펴 보겠습니다.

렌더링 대 커밋 단계

구성 요소는 두 가지 높은 수준의 단계를 거칩니다.

  • 렌더링 단계 렌더링 이전 DOM에서의 변경을 결정하고, 다음과 같은 메소드를 호출 componentWillMount, rendersetState(다른 사람의 사이)
  • 커밋 이름에서 알 수 있듯이, DOM에 대한 변경 사항을 (렌더링 단계가 결정하는 것이) 커밋을 포함하여 메소드를 호출, 단계 componentDidMount, componentDidUpdatecomponentDidCatch

참조는 커밋 단계에서 구현되어야합니다.

반면 커밋 단계는 한 번만 호출되며 부작용을 정의해야하는 단계이며 일반적으로 한 번만 인스턴스화되기를 원하는 것을 말합니다.

부작용은 실행되는 함수의 범위를 벗어난 무언가에 영향을 미치는 모든 것입니다. API 요청, 웹 소켓, 타이머, 로거, 심지어 Ref의 모든 것이 될 수 있습니다.

구성 요소가 여러 번 다시 렌더링하고 해당 단계에서 Ref를 다시 초기화하는 경우 해당 Ref 로직이 동일한 횟수로 실행됩니다. 이는 React에서 Concurrent Mode를 고려할 때 더 걱정 스럽습니다. 즉, 컴포넌트의 렌더링 단계가 초기 렌더링에서 여러 번 실행될 수 있습니다.

동시 모드는 렌더링 프로세스를 조각으로 나누고, 우선 순위가 더 높은 다른 비동기 프로세스를 실행해야 할 때 작업을 일시 중지하고 다시 시작하기 때문입니다. 그 결과 커밋하기 전에 렌더 단계 수명주기 메서드가 두 번 이상 (또는 오류가있는 경우 전혀 호출되지 않음) 호출 될 가능성이 있습니다.

이것은 부작용이나 구성 요소의 범위를 벗어난 것을 정의하는 것으로 신뢰할 수 없습니다. 개발할 때 이러한 함정에 빠지지 않도록하기 위해 할 수있는 일이 많이 있습니다.

1. 엄격 모드 활용

가장 먼저 할 수있는 일은 Strict Mode를 구현하는 것 입니다. Strict Mode는 콘솔을 통해 앱 코딩 방식과 관련된 다양한 문제를 강조하도록 설계되었으며 예상치 못한 부작용감지하는 데 전념하는 전체 섹션이 있습니다 .

Strict Mode는 JXS를 통해 전체 앱에서 또는 특정 수의 하위 구성 요소에서만 활성화 할 수 있습니다. 전체 앱을 래핑하여 엄격 모드를 적용합니다.

// wrapping your app in Strict Mode
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
, document.getElementById('root'));

이것은 기능적 구성 요소의 논리가 올바르게 설계되었는지 확인하기 위해 선호하는 접근 방식이지만 다른 옵션을 사용할 수 있습니다.

2. 동시 모드에서 앱 테스트

보다 직접적인 접근 방식은 동시 모드에서 앱을 개발하는 것입니다. 그러면 개발중인 문제에도 플래그가 지정됩니다.

2018 년 11 월에 게시React의 로드맵 블로그 게시물을 참조하면 요소의 하위 집합을 래핑하거나 전체 애플리케이션을 동시 모드 선언으로 래핑하는 두 가지 방법으로 동시 모드를 활성화 할 수 있습니다.

// section of an app (not final API)
<React.unstable_ConcurrentMode>
  <MyComponent />
</React.unstable_ConcurrentMode>
// entire app (not final API)
ReactDOM.unstable_createRoot(domNode).render(<App />);

진행중인 작업의 불안정한 특성으로 인해 최종 릴리스까지 동시 모드 지원 앱의 프로덕션 빌드를 배포하지 않는 것이 좋습니다.

위의 내용을 염두에두고 이제 useRef커밋 단계에서의 실제 완료된 구현을 확인하겠습니다 .

useEffect로 useRef 구현

우리가 논의한 예측할 수없는 Ref 동작을 피하는 해결책은 useEffect또는 useLayoutEffect후크 내부에 Ref 부작용을 구현하는 것 입니다.

왜 이런거야? 공식 문서에 따르면 변형, 구독, 타이머 및 로깅과 같은 부작용은 함수 구성 요소의 본문 내에서 허용되지 않기 때문입니다. 이 본체 내부의 모든 로직은 렌더링 단계에서 실행되므로 UI에서 혼란스러운 버그와 불일치가 발생합니다.

useEffect반면 에 브라우저에서 실제 DOM이 업데이트 된 한 번 실행 됩니다. useEffect따라서 구성 요소의 커밋 단계에서 실행됩니다.

이를 증명하기 위해 간단한 카운터 구성 요소를 만들 수 있습니다. 여기서 구성 요소가 다시 렌더링 될 때마다 계산합니다. 버튼 클릭시 구성 요소를 강제로 다시 렌더링하기 위해 useReducer후크도 구현되었습니다.

위의 예에서는 refCount.current값으로 시작 0하고 구성 요소 업데이트의 커밋 단계에서 증가합니다.

주 함수 블록에서이 증분을 만들면 렌더링 함수가 반환되기 전에 렌더링 단계에서 업데이트가 수행되어 증분이 예측할 수없는 중복이 발생한다는 것을 기억하십시오.

이제 DOM 요소를 참조하고 ref를 통해 이벤트 리스너를 연결하는 다른 구성 요소를 살펴 보겠습니다. 이벤트 리스너는 다시 useEffect후크에 정의됩니다 . 또한의 반환 함수 useEffect는 구성 요소가 마운트 해제 될 때 트리거되는 정리 수단으로 작동합니다. 여기서 ref에서 이벤트 리스너를 제거 할 수 있습니다.

이제 텍스트 입력 안팎을 클릭하면 해당 console.log출력에서 텍스트 입력에 초점이 맞춰지고 흐릿 해짐을 알립니다.

이 개념을 몇 단계 더 진행해 보겠습니다. 다음 예제는 refInputRef를 통해 버튼 요소의 클래스를 조작합니다 . 또한 텍스트 입력 테두리와 텍스트 색상을 변경 <Wrapper />하는 active클래스 를 정의하기 위해 Styled Component를 도입했습니다 .

이제 상태 업데이트에 의존하지 않고 CSS 조작이 일부 있습니다.

데모의 마지막 단계는 이전에 설명한 내용을 구현하는 것입니다. 제출 버튼을 구현하고 텍스트 입력 값이 비어있는 경우 비활성화합니다. 이를 useRef위해 제출 버튼 자체에 대한 추가 후크를 도입했습니다 . disabled속성 을 토글하기 위해 setAttributeremoveAttributeJavascript API가 refSubmitRef.

전체 솔루션은 다음과 같습니다.

제출 버튼의 disabled속성은 텍스트 입력 외부를 클릭 (또는 탭)하면 업데이트되거나 흐리게 표시 될 때 양식이 유효한지 판단하는 데 다소 자연스러운 시간입니다.

추가 참고 사항

이 기사의 마지막 섹션에서는 useRef.

useEffect로 인해 문제가 발생할 때 useLayoutEffect 사용

이 기사의 시작 부분에서 우리 useLayoutEffectuseRef. 및 클래스 구성 요소 수명주기 메서드 와 useLayoutEffect동일한 단계에서 발생 하므로 .componentDidMountcomponentDidUpdateuseEffect

그러나 공식 문서에서는 개발자가 useEffect주로 사용을 시도 하고 useLayoutEffect문제가 발생하면 대체 할 것을 권장 합니다. useLayoutEffect모든 DOM 변형 / 업데이트가 발생한 후에 만 ​​동 기적으로 호출 되므로을 사용 하면 속도가 약간 저하 될 수 있습니다. 이 세부 사항을 제외하면 useEffect.

useRef의 전달

클래스 구성 요소에서 초기화 된 전달 참조 와 마찬가지로 useRef동일한 규칙을 따르는 한 후크 를 통해 초기화 된 참조를 전달할 수도 있습니다 . ref를“ ref”prop 으로 전달하지 마십시오. 이것은 React에서 예약 된 속성 이름이며 오류를 유발합니다. 대신 forwardRef.

...
// defining `refInput` within `App`, forwarding it to `MyInput`
function App () {
  const refInput = useRef();
return <MyInput 
    forwardRef={refInput};
}

// referencing `input` element with `forwardRef` in child component
function MyInput (props) {
  // verifying `input` is referenced correctly after DOM updates
  useLayoutEffect(() => {
    console.log(props.forwardRef.current);
  });
const { forwardRef } = props;
return (
    <input
      ref={forwardRef}
      type="submit"
      value="Submit"
  />);
}

이벤트를 수신 할뿐만 아니라 이벤트를 트리거 할 수도 있습니다. 우리가 이것을 보여주지 않으면 데모는 완전하지 않을 것입니다. 아래 구성 요소에서 버튼을 클릭하면 useRef를 사용하여 또 다른 텍스트 입력에 초점을 맞 춥니 다.

// focussing an element with a button press
function TextInput () {
const refInput = useRef();
function handleFocus () {
    refInput.current.focus();
  }
return (
    <>
      <input ref={refInput} placeholder="Input Here..." />
      <button onClick={handleFocus}>Focus Input</button>
    </>
  );
}

요약하자면

이 문서는 useRef구성 요소 수명주기를 고려하여 참조를 올바르게 구현하는 방법과에 대한 요약 입니다. 참조를 사용하는 것은 여기서 논의한 사용 사례에 대한 편리한 방법이 될 수 있습니다.

  • 포커스, 흐림, 비활성화 및 양식 관리와 관련된 기타 속성을 사용하여 입력을 세부적으로 관리하려면
  • 요소에서 클래스를 추가하거나 제거하려면 (전환 또는 키 프레임 애니메이션 제어)
  • 공식 문서에서 권장하는 다른 사용 사례는 미디어 플레이어와 같은 다른 HTML5 라이브러리와 상호 작용하는 것입니다. 이러한 라이브러리는 React 상태를 통해 액세스 할 수 없으며 Refs는 구성 요소의 수명주기와 일치하면서 다른 요소와 직접 상호 작용할 수있는 폴백을 제공합니다.
React Ref를 사용하는 방법

Suggested posts

Kickass GitHub 프로필 페이지를 만드는 방법

새로운 특수 리포지토리 및 GitHub 작업으로 놀라운 GitHub 프로필을 만듭니다.

Kickass GitHub 프로필 페이지를 만드는 방법

이 자습서는 비디오로도 제공됩니다.이 링크를 클릭하십시오. 이 기사에서는 눈에 잘 띄고보기 좋은 Github 프로필 페이지를 만드는 방법을 볼 수 있습니다.

이미지는 크리에이터로서 콘텐츠를 만들거나 깨뜨릴 수 있습니다.

이미지는 크리에이터로서 콘텐츠를 만들거나 깨뜨릴 수 있습니다.

지루한 그림으로 흥미 진진한 기사를 읽고 싶은 사람. 사람들은 제정신이 아닙니다. 그것은 당신이 쓰는 방식 때문입니다.

Related posts

성능 최적화 된 A / B 테스트 솔루션

성능 최적화 된 A / B 테스트 솔루션

의제 : 소개 : TL;하지만 읽을 수 있습니다. A / B 테스트, CloudFront 및 Lamba @ edge에 대해 이미 알고있는 경우 AWS Lambda @ edge를 사용한 A / B 테스트로 직접 이동하십시오. A / B 테스트 란 무엇입니까? A / B 테스트는 웹 사이트의 두 가지 버전에 대한 사용자의 참여를 비교하는 데 초점을 맞춘 UX 연구 방법론입니다.

fp-ts (Typescript)에서 Option 및 둘 중 하나 사용

저는 함수형 프로그래밍을 좋아합니다. 몇 년 동안 실수를하거나 토끼 구멍을 뚫는 것으로부터 저를 몇 번 구해 주었기 때문입니다. 동일한 입력이 주어지면 출력이 항상 동일하다는 것을 알면 안심입니다.

Syncfusion Blazor 파일 업로드 구성 요소에서 이미지를 미리 보는 방법

Syncfusion Blazor 파일 업로드 구성 요소에서 이미지를 미리 보는 방법

Syncfusion Blazor 파일 업로드는 하나 이상의 파일, 이미지, 문서, 오디오, 비디오 및 기타 파일을 서버에 업로드하기위한 구성 요소입니다. 여러 파일 선택, 진행률 표시 줄, 자동 업로드, 끌어서 놓기, 폴더 (디렉터리) 업로드, 파일을 포함하는 다양한 기능을 갖춘 HTML5 업로드 구성 요소 (<input type =”file”>)의 확장 버전입니다. 검증 등.

6 React 개발자로서 후회

내가 일찍했으면하는 것

6 React 개발자로서 후회

React는 배울 수있는 훌륭한 도구입니다. 그것은 우리가 우리 자신의 방식으로 일을 할 수있게합니다.