React에서 ref에 대한 올바른 proptype은 무엇입니까?


85

내 redux 저장소에 ref를 저장하고 mapStateToProps를 사용하여 액세스가 필요한 구성 요소에 대한 참조를 노출합니다.

저장된 참조는 다음과 같습니다.

ref={node => this.myRefToBePutInReduxGlobalStore = node}

이 심판에 대한 올바른 propType은 무엇입니까?


8
ref는 직렬화 할 수 없기 때문에 Redux 스토어에 넣는 것은 좋은 생각이 아닙니다. 그럼에도 불구하고 refprop에 전달 된 값 은 첫 번째 인수가 DOM 요소에 대한 참조이거나 null 인 함수입니다. 그것은 기능 입니다.
rishat

5
당신은 사용할 수 없습니다 propType 에 대한 refs,하지만 당신은 그것을 사용할 수 있습니다 props. redux 저장소에 전달하기 때문에 proplike 로 표시됩니다 this.props.myRefToBePutInReduxGlobalStore. myRefToBePutInReduxGlobalStore노드의 유형해야한다, 그래서 PropTypes.node당신을 위해 일한다
그 이유

PropType.objectref는 기본적으로 객체 인 클래스 인스턴스이기 때문에 그렇게해야한다고 생각 합니다. 당신이 소품으로 ref 요소를 통과 할 때 따라서이 될 것 객체
Hriday 모디

답변:


96

TL; DR

a div또는 an 과 같은 기본 DOM 요소 만 예상하는 ref 유형을 prop하려는 경우 input올바른 정의는 다음과 같습니다.

refProp: PropTypes.oneOfType([
    // Either a function
    PropTypes.func, 
    // Or the instance of a DOM native element (see the note about SSR)
    PropTypes.shape({ current: PropTypes.instanceOf(Element) })
])

원본 게시물에 설명 된 특정 문제에 대한 답변

OP 질문의 예에서 선언해야하는 것은 ref prop 유형이 아니라 ref가 가리키는 항목이며 mapStateToProps. DOM 요소의 소품 유형은 다음과 같습니다 myRefToBePutInReduxGlobalStore: PropTypes.instanceOf(Element)(DOM 요소 인 경우). 하지만 다음과 같습니다.

  1. 이름 바꾸기 myElementToBePutInReduxGlobalStore(요소는 참조가 아님)
  2. 직렬화 불가능한 데이터를 redux 저장소에 저장하지 마십시오.
  3. React 엔지니어 Seb Markbage의 설명대로 소품에 요소를 전달하지 마십시오.

실제 질문에 대한 긴 답변

Q : React에서 ref에 대한 올바른 proptype은 무엇입니까?

사용 사례 예 :

function FancyInput({ inputRef }) {
    return (
        <div className="fancy">
            Fancy input
            <input ref={inputRef} />
        </div>
    )
}

FancyInput.propTypes = {
    inputRef: ???   // What is the correct prop type here?
}

function App(props) {
    const inputRef = React.useRef()
    useLayoutEffect(function focusWhenStuffChange() {
        inputRef.current?.focus()
    }, [props.stuff])
    return <FancyInput inputRef={inputRef} />
}

오늘날 반응에는 두 가지 종류의 ref가 존재합니다.

  1. 다음과 같은 객체 : { current: [something] }일반적으로 React.createRef()도우미 또는 React.useRef()후크에 의해 생성됨
  2. [something]인수로 받을 콜백 함수 (OP 예제에서와 같이)

참고 : 역사적으로 문자열 ref를 사용할 수도 있지만 레거시로 간주 되며 반응에서 제거됩니다.

두 번째 항목은 매우 간단하며 다음 소품 유형이 필요합니다 PropTypes.func..

첫 번째 옵션은 ref가 가리키는 요소 유형을 지정하려고 할 수 있기 때문에 덜 명확합니다.

많은 좋은 답변

ref DOM 요소가 아닌 다른 것을 가리킬 수 있습니다.

완전히 유연 해지고 싶다면 :

refProp: PropTypes.oneOfType([
    PropTypes.func, 
    PropTypes.shape({ current: PropTypes.any })
])

위의 내용은 current속성 이있는 객체 참조의 모양을 강제합니다 . 모든 종류의 심판에 대해 항상 작동합니다. 을 개발할 때 불일치를 발견하는 방법 인 prop 유형을 사용 하려면 이 정도면 충분할 것입니다. 모양을 가진 객체가 소품에 전달 되면 실제 참조 가 아닐 가능성매우 낮습니다 .{ current: [any] }refToForward

그러나 컴포넌트가 어떤 종류의 ref도 기대하지 않고 특정 유형 만 필요하다고 선언 할 수 있습니다 .

나는 ref를 선언하는 몇 가지 다른 방법을 보여주는 샌드 박스를 설정했습니다. 여기에서 찾을 수 있습니다 .


당신은 단지 기본 입력 요소에 심판을 가리키는 경우를 예측하지 어떤 HTML Element:

refProp: PropTypes.oneOfType([
    PropTypes.func, 
    PropTypes.shape({ current: PropTypes.instanceOf(HTMLInputElement) })
])

React 클래스 구성 요소를 가리키는 ref 만 예상하는 경우 :

refProp: PropTypes.oneOfType([
    PropTypes.func, 
    PropTypes.shape({ current: PropTypes.instanceOf(Component) })
])

useImperativeHandle일부 공용 메서드를 노출 하는 데 사용하는 기능 구성 요소를 가리키는 참조 만 예상하는 경우 :

refProp: PropTypes.oneOfType([
    PropTypes.func, 
    PropTypes.shape({ current: PropTypes.object })
])

참고 : 위의 prop 유형은 모두 기본 자바 스크립트를 상속하므로 반응 구성 요소와 기본 DOM 요소도 포함하므로 흥미 롭습니다. Object


ref에 대한 prop 유형을 선언하는 좋은 방법은 없습니다. 사용법에 따라 다릅니다. 참조가 매우 식별 된 것을 가리키는 경우 특정 소품 유형을 추가 할 가치가 있습니다. 그렇지 않으면 일반적인 모양을 확인하는 것만으로 충분 해 보입니다.


서버 측 렌더링에 대한 참고 사항

코드가 서버에서 실행되어야하는 경우, 이미 DOM 환경을 폴리 필하지 않는 한 Element또는 다른 클라이언트 측 유형이 undefinedNodeJS에 있습니다. 다음 shim을 사용하여 지원할 수 있습니다.

Element = typeof Element === 'undefined' ? function(){} : Element

다음 React Docs 페이지는 refs, object 및 callbacks 사용 방법후크 사용 방법에 대한 자세한 정보 제공합니다.useRef

@Rahul Sagore, @Ferenk Kamra, @svnm 및 @Kamuela Franco에 감사드립니다.


2
그것은 제공 Element서버 측 렌더링에 정의되어 있지 않습니다. 그것에 대한 해결책이 있습니까?
Rahul Sagore 19.01.08

좋은 지적. 이 심은 어떻습니까 : Element = typeof Element === 'undefined' ? function(){} : Element(Github 문제에서 Ryan Florence가 제안 함). 그것이 당신을 위해 작동한다면 내 대답에 추가 할 수 있습니다.
Pandaiolo

나는 그것을 알아 내고 이것을 추가했습니다 if (!isBrowser) { global.Element = null; }. 나를 위해 일했습니다. isBrowser = typeof window !== 'undefined';
Rahul Sagore

좋은 대답입니다. 나는 TL; DR이 응답의 맨 위에 있기를 바랍니다.
Kamuela Franco

12

@Pandaiolo의 게시물과 매우 유사합니다.

PropTypes.elementType 이제 추가되었습니다

forwardedRef: PropTypes.oneOfType([
  PropTypes.func,
  PropTypes.shape({ current: PropTypes.elementType })
]),

PropTypes> = 15.7.0을 사용 PropTypes.elementType하는 경우이 PR 에서 2019 년 2 월 10 일에 추가되었습니다.


감사합니다 @svnm, 나는 이것을 반영하기 위해 내 대답을 업데이트하여 더 간단하게 만듭니다!
Pandaiolo

1
결국 그것은 elementType저에게 효과가 없었기 때문에 실제로 샌드 박스에서 ref가 가리킬 수있는 여러 종류의 구성 요소에서 여러 가지 소품 유형을 테스트했습니다. 결과는 다음과 같습니다. codesandbox.io/s/loving-benz-w6fbh . 모든 가능성을 다룰 수는 없지만 DOM 요소에 대한 올바른 proptype은 instanceOf(Element)(또는 object), 클래스의 경우 instanceOf(Component)(또는 object)이고 useImperativeHandle이를 사용하는 기능적 구성 요소의 특정 사용 사례에 대해서는 입니다 object. 생각?
Pandaiolo

9

나는 선호하는 방법 만 확인하고 PropType.object 는 그다지 가치가 없기 때문에 이것을 사용하게되었습니다.

PropTypes.shape({ current: PropTypes.instanceOf(Element) })

1

위의 답변을 모두 확인했는데 반응에서 경고가 나와서 많이 조사해서 정답을 얻었습니다.

import React, { Component } from 'react';

ComponentName.propTypes = {
  reference: PropTypes.oneOfType([
    PropTypes.func,
    PropTypes.shape({ current: PropTypes.instanceOf(Component) }),
  ]),
};
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.