क्लास आधारित घटक में React.forwardRef का उपयोग कैसे करें?


112

मैं React.forwardRef का उपयोग करने की कोशिश कर रहा हूं, लेकिन इसे वर्ग आधारित घटक (HOC नहीं) में काम करने के लिए कैसे प्राप्त किया जाए, इस पर ट्रिपिंग।

डॉक्स उदाहरण तत्वों और कार्यात्मक घटकों का उपयोग करते हैं, यहां तक ​​कि उच्च क्रम घटकों के लिए कार्यों में कक्षाएं लपेटते हैं।

तो, उनकी फ़ाइल में कुछ इस तरह से शुरू ref.js:

const TextInput = React.forwardRef(
    (props, ref) => (<input type="text" placeholder="Hello World" ref={ref} />)
);

और इसके बजाय इसे कुछ इस तरह परिभाषित करना है:

class TextInput extends React.Component {
  render() {
    let { props, ref } = React.forwardRef((props, ref) => ({ props, ref }));
    return <input type="text" placeholder="Hello World" ref={ref} />;
  }
}

या

class TextInput extends React.Component {
  render() { 
    return (
      React.forwardRef((props, ref) => (<input type="text" placeholder="Hello World" ref={ref} />))
    );
  }
}

केवल काम: /

इसके अलावा, मुझे पता है कि मुझे पता है, रेफरी प्रतिक्रिया तरीका नहीं है। मैं एक तीसरे पक्ष के कैनवास पुस्तकालय का उपयोग करने की कोशिश कर रहा हूं, और उनके कुछ उपकरणों को अलग-अलग घटकों में जोड़ना चाहूंगा, इसलिए मुझे इवेंट श्रोताओं की आवश्यकता है, इसलिए मुझे जीवनचक्र विधियों की आवश्यकता है। यह बाद में एक अलग मार्ग पर जा सकता है, लेकिन मैं यह कोशिश करना चाहता हूं।

डॉक्स कहते हैं कि यह संभव है!

Ref अग्रेषण DOM घटकों तक सीमित नहीं है। तुम भी वर्ग घटक उदाहरण के लिए रेफरी आगे कर सकते हैं।

इस अनुभाग में नोट से

लेकिन तब वे सिर्फ कक्षाओं के बजाय एचओसी का उपयोग करते हैं।

जवाबों:


108

हमेशा के लिए एक ही प्रोप का उपयोग करने का विचार refएक सहायक के साथ वर्ग निर्यात को समीपता द्वारा प्राप्त किया जा सकता है।

class ElemComponent extends Component {
  render() {
    return (
      <div ref={this.props.innerRef}>
        Div has ref
      </div>
    )
  }
}

export default React.forwardRef((props, ref) => <ElemComponent 
  innerRef={ref} {...props}
/>);

तो मूल रूप से, हाँ, हम आगे रेफरी के लिए एक अलग प्रोप करने के लिए मजबूर हैं, लेकिन यह हब के तहत किया जा सकता है। यह महत्वपूर्ण है कि जनता इसे एक सामान्य रेफरी के रूप में उपयोग करे।


4
यदि आप अपने घटक को एचओसी में लिपटे जैसे रिएक्ट- connectरिडक्स या मैटरियल-यूई के हैं तो withStylesक्या करते हैं?
जे। हेस्टर

क्या समस्या है connectया withStyles? आपको forwardRefश्रृंखला में सबसे कम घटक के लिए रेफरी पास करने के लिए "सुरक्षित" प्रोप के साथ सभी एचओसी को लपेटना चाहिए ।
श्री ब्र।

जब आप setState का उपयोग कर रहे हैं, तो एंजाइम में यह परीक्षण करने के बारे में कोई जानकारी
शून्य_

क्षमा करें, मुझे थोड़ा और विवरण चाहिए। निश्चित नहीं है कि समस्या क्या है।
श्री ब्र।

2
मुझे मिल रहा है: Invariant Violation: ऑब्जेक्ट एक रिएक्ट बच्चे के रूप में मान्य नहीं हैं (पाया: कुंजियों के साथ ऑब्जेक्ट {$$ टाइपो, रेंडर})। यदि आप बच्चों के संग्रह को प्रस्तुत करना चाहते हैं, तो इसके बजाय एक सरणी का उपयोग करें।
ब्रायन लफ़नेन

9
class BeautifulInput extends React.Component {
  const { innerRef, ...props } = this.props;
  render() (
    return (
      <div style={{backgroundColor: "blue"}}>
        <input ref={innerRef} {...props} />
      </div>
    )
  )
}

const BeautifulInputForwardingRef = React.forwardRef((props, ref) => (
  <BeautifulInput {...props} innerRef={ref}/>
));

const App = () => (
  <BeautifulInputForwardingRef ref={ref => ref && ref.focus()} />
)

एक वर्ग को रेफरी को अग्रेषित करने के लिए आपको एक अलग प्रोप नाम का उपयोग करने की आवश्यकता है। innerRefआमतौर पर कई पुस्तकालयों में उपयोग किया जाता है।


आपके कोड beautifulInputElementमें रिएक्ट एलिमेंट के बजाय एक फ़ंक्शन अधिक है, यह इस तरह होना चाहिएconst beautifulInputElement = <BeautifulInputForwardingRef ref={ref => ref && ref.focus()} />
ओलिवियर बोइस

8

असल में, यह सिर्फ एक HOC फ़ंक्शन है। यदि आप इसे कक्षा के साथ उपयोग करना चाहते हैं, तो आप इसे स्वयं कर सकते हैं और नियमित रूप से सहारा ले सकते हैं।

class TextInput extends React.Component {
    render() {
        <input ref={this.props.forwardRef} />
    }
}

const ref = React.createRef();
<TextInput forwardRef={ref} />

इस पैटर्न का उपयोग उदाहरण के लिए किया जाता है styled-componentsऔर इसे innerRefवहां बुलाया जाता है।


3
एक अलग नाम वाले प्रोप का उपयोग करना innerRefपूरी तरह से बिंदु को याद कर रहा है। लक्ष्य पूर्ण पारदर्शिता है: मुझे इसका इलाज करने में सक्षम होना चाहिए <FancyButton>जैसे कि यह एक नियमित डोम तत्व था, लेकिन स्टाइल-घटकों के दृष्टिकोण का उपयोग करते हुए, मुझे यह याद रखना होगा कि यह घटक सिर्फ के बजाय रेफ के लिए एक मनमाने ढंग से नामित प्रोप का उपयोग करता है ref
user128216

2
किसी भी मामले में, स्टाइल-घटकों का उपयोग करने वाले बच्चे को रेफ पास करने के पक्ष में समर्थन छोड़ने काinnerRef इरादा है React.forwardRef, जिसे ओपी पूरा करने की कोशिश कर रहा है।
user128216

5

यदि आप चाहें तो इसे उच्च-क्रम के घटक के साथ पूरा किया जा सकता है:

import React, { forwardRef } from 'react'

const withForwardedRef = Comp => {
  const handle = (props, ref) =>
    <Comp {...props} forwardedRef={ref} />

  const name = Comp.displayName || Comp.name
  handle.displayName = `withForwardedRef(${name})`

  return forwardRef(handle)
}

export default withForwardedRef

और फिर अपने घटक फ़ाइल में:

class Boop extends React.Component {
  render() {
    const { forwardedRef } = this.props

    return (
      <div ref={forwardedRef} />
    )
  }
}

export default withForwardedRef(Boop)

मैंने परीक्षण के साथ काम को आगे बढ़ाया और इसके लिए एक पैकेज प्रकाशित किया react-with-forwarded-ref: https://www.npmjs.com/package/react-with-forwarded-ref


3

इनसे आपको कई अंतर घटकों में पुन: उपयोग करने की आवश्यकता है, आप इस क्षमता को कुछ इस तरह निर्यात कर सकते हैं withForwardingRef

const withForwardingRef = <Props extends {[_: string]: any}>(BaseComponent: React.ReactType<Props>) =>
    React.forwardRef((props, ref) => <BaseComponent {...props} forwardedRef={ref} />);

export default withForwardingRef;

उपयोग:

const Comp = ({forwardedRef}) => (
 <input ref={forwardedRef} />
)
const EnhanceComponent = withForwardingRef<Props>(Comp);  // Now Comp has a prop called forwardedRef
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.