it-swarm.com.de

Wie verwende ich React.forwardRef in einer klassenbasierten Komponente?

Ich versuche, React.forwardRef zu verwenden, stolpere jedoch, wie es in einer klassenbasierten Komponente (nicht HOC) zum Laufen gebracht wird.

In den docs-Beispielen werden Elemente und Funktionskomponenten verwendet, und sogar Klassen werden in Funktionen für Komponenten höherer Ordnung eingeschlossen.

Beginnen wir also mit etwas wie this in ihrer ref.js-Datei:

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

und stattdessen es als etwas wie das definieren:

class TextInput extends React.Component {

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

}

oder

class TextInput extends React.Component {

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

nur arbeiten: /

Ich weiß auch, dass Refs nicht der Reaktionsweg sind. Ich versuche, eine Leinwandbibliothek eines Drittanbieters zu verwenden, und möchte einige ihrer Tools in separaten Komponenten hinzufügen. Daher brauche ich Ereignis-Listener, also brauche ich Lebenszyklusmethoden. Es kann später eine andere Route gehen, aber ich möchte dies versuchen.

Die Dokumente sagen, dass es möglich ist!

Die Weiterleitung von Referenzen ist nicht auf DOM-Komponenten beschränkt. Sie können Refs auch an Klassenkomponenteninstanzen weiterleiten.

aus dem Hinweis in diesem Abschnitt.

Aber dann verwenden sie HOCs statt nur Klassen.

38
Han Lazarus

Die Idee, immer die gleiche Requisite für die ref zu verwenden, kann durch das Proxying des Klassenexports mit einem Helfer erreicht werden. 

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}/>);

Im Grunde, ja, wir sind gezwungen, eine andere Stütze zu haben, um ref weiterzuleiten, aber es kann unter der Nabe gemacht werden. Es ist wichtig, dass die Öffentlichkeit es als normalen Hinweis verwendet. 

23
Mr Br
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()} />
)

Sie müssen einen anderen Namen verwenden, um den Ref an eine Klasse weiterzuleiten. innerRef wird häufig in vielen Bibliotheken verwendet.

3

Im Grunde ist dies nur eine HOC-Funktion. Wenn Sie es mit dem Unterricht verwenden wollten, können Sie dies selbst tun und reguläre Requisiten verwenden.

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

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

Dieses Muster wird zum Beispiel in styled-components verwendet und dort innerRef genannt.

Wenn Sie dies in vielen unterschiedlichen Komponenten wiederverwenden müssen, können Sie diese Fähigkeit in etwas wie withForwardingRef exportieren

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

export default withForwardingRef;

verwendungszweck:

const Comp = ({forwardedRef}) => (
 <input ref={forwardedRef} />
)
const EnhanceComponent = withForwardingRef<Props>(Comp);  // Now Comp has a prop called forwardedRef
2
orepor

Dies kann mit einer Komponente höherer Ordnung erreicht werden, wenn Sie möchten:

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

Und dann in Ihrer Komponentendatei:

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

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

export default withForwardedRef(Boop)

Ich habe die Arbeit im Voraus mit Tests durchgeführt und dazu ein Paket veröffentlicht: react-with-forwarded-ref: https://www.npmjs.com/package/react-with-forwarded-ref

1
rpearce

Genau das sagt die Referenz. Es zeigt, wie forwardRef mit DOM-Komponenten verwendet wird:

const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

// You can now get a ref directly to the DOM button:
const ref = React.createRef();
<FancyButton ref={ref}>Click me!</FancyButton>;

Dabei enthält ref eine Referenz auf das DOM-Element.

Es ist möglich, forwardRef mit Klassenkomponenten auf dieselbe Weise zu verwenden:

const FancyButton = React.forwardRef((props, ref) => (
  <SomeClassComponent ref={ref} />
));

Dabei enthält ref eine Referenz auf die Klasseninstanz.

0
estus