Wie übergebe ich eine Reaktionskomponente in eine andere Reaktionskomponente, um den Inhalt der ersten Komponente zu übertragen?


215

Gibt es eine Möglichkeit, eine Komponente in eine andere Reaktionskomponente zu übertragen? Ich möchte eine Modellreaktionskomponente erstellen und eine andere Reaktionskomponente übergeben, um diesen Inhalt zu transklamieren.

Bearbeiten: Hier ist ein ReactJS-Codepen, der veranschaulicht, was ich versuche zu tun. http://codepen.io/aallbrig/pen/bEhjo

HTML

<div id="my-component">
    <p>Hi!</p>
</div>

ReactJS

/**@jsx React.DOM*/

var BasicTransclusion = React.createClass({
  render: function() {
    // Below 'Added title' should be the child content of <p>Hi!</p>
    return (
      <div>
        <p> Added title </p>
        {this.props.children}
      </div>
    )
  }
});

React.renderComponent(BasicTransclusion(), document.getElementById('my-component'));

Antworten:


197

Sie können verwenden this.props.children, um alle untergeordneten Elemente zu rendern, die die Komponente enthält:

const Wrap = ({ children }) => <div>{children}</div>

export default () => <Wrap><h1>Hello word</h1></Wrap>

4
Ich würde diese Antwort verwenden. this.props.childrenist Teil der Komponenten-API und wird voraussichtlich auf diese Weise verwendet. Die Beispiele des React-Teams verwenden diese Technik, beispielsweise beim Übertragen von Requisiten und beim Sprechen über ein einzelnes Kind .
Ross Allen

Aus meinem Kommentar unten: Wenn Sie es als Requisite übergeben, können Sie ihm sogar einen Namen geben und propTypes verwenden, um check zu tippen.
Rückkehrea

1
@ AndrewAllbright: Dein Beispiel hat keine Kinder bestanden. Dies funktioniert: codepen.io/ssorallen/pen/Dyjmk
Ross Allen

Und falls Sie dann die DOM-Knoten der Kinder erhalten möchten
ericsoco

124

Hinweis versehen ich eine tiefer gehende Antwort hier

Laufzeit-Wrapper:

Es ist der idiomatischste Weg.

const Wrapper = ({children}) => (
  <div>
    <div>header</div>
    <div>{children}</div>
    <div>footer</div>
  </div>
);

const App = () => <div>Hello</div>;

const WrappedApp = () => (
  <Wrapper>
    <App/>
  </Wrapper>
);

Beachten Sie, dass dies childreneine "spezielle Requisite" in React ist. Das obige Beispiel ist syntaktischer Zucker und entspricht (fast)<Wrapper children={<App/>}/>


Initialisierungs-Wrapper / HOC

Sie können eine Komponente höherer Ordnung ( Higher Order Component, HOC) verwenden. Sie wurden kürzlich zum offiziellen Dokument hinzugefügt .

// Signature may look fancy but it's just 
// a function that takes a component and returns a new component
const wrapHOC = (WrappedComponent) => (props) => (
  <div>
    <div>header</div>
    <div><WrappedComponent {...props}/></div>
    <div>footer</div>
  </div>
)

const App = () => <div>Hello</div>;

const WrappedApp = wrapHOC(App);

Dies kann zu (wenig) besseren Leistungen führen, da die Wrapper-Komponente das Rendern mit shouldComponentUpdate einen Schritt vorausschließen kann, während bei einem Laufzeit-Wrapper die untergeordnete Requisite wahrscheinlich immer ein anderes ReactElement ist und ein erneutes Rendern verursacht auch wenn Ihre Komponenten PureComponent erweitern.

Beachten Sie, dass connectRedux früher ein Laufzeit-Wrapper war, aber in ein HOC geändert wurde, da es unnötige Renderings vermeiden kann, wenn Sie die pureOption verwenden (was standardmäßig der Fall ist).

Sie sollten während der Renderphase niemals ein HOC aufrufen, da das Erstellen von React-Komponenten teuer sein kann. Sie sollten diese Wrapper lieber bei der Initialisierung aufrufen.


Beachten Sie, dass die HOC-Version bei Verwendung von Funktionskomponenten wie oben keine nützliche Optimierung bietet, da zustandslose Funktionskomponenten nicht implementiert werden shouldComponentUpdate

Weitere Erklärungen hier: https://stackoverflow.com/a/31564812/82609


29
const ParentComponent = (props) => {
  return(
    {props.childComponent}
    //...additional JSX...
  )
}

//import component
import MyComponent from //...where ever

//place in var
const myComponent = <MyComponent />

//pass as prop
<ParentComponent childComponent={myComponent} />

Dies wäre richtig gewesen, wenn es ... React 15.x erlaubt Ihnen nicht, eine Komponente mit mehreren Knoten zurückzugeben. React 16 (auch bekannt als React Fibre) ermöglicht mehrere Knoten. Hier ist das Update für Ihr Codebeispiel: const ParentComponent = (Requisiten) => ({props.childComponent}); importiere MyComponent von //...wover const myComponent = <MyComponent /> // als Requisite übergeben <ParentComponent childComponent = {myComponent} />
Andrew Allbright

13

Facebook empfiehlt die Verwendung zustandsloser Komponenten. Quelle: https://facebook.github.io/react/docs/reusable-components.html

In einer idealen Welt wären die meisten Ihrer Komponenten zustandslose Funktionen, da wir in Zukunft auch Leistungsoptimierungen für diese Komponenten vornehmen können, indem unnötige Überprüfungen und Speicherzuweisungen vermieden werden. Dies ist nach Möglichkeit das empfohlene Muster.

function Label(props){
    return <span>{props.label}</span>;
}

function Hello(props){
    return <div>{props.label}{props.name}</div>;
}

var hello = Hello({name:"Joe", label:Label({label:"I am "})});

ReactDOM.render(hello,mountNode);

13

Sie können es als normale Requisite übergeben: foo={<ComponentOne />}

Beispielsweise:

const ComponentOne = () => <div>Hello world!</div>
const ComponentTwo = () => (
  <div>
    <div>Hola el mundo!</div>
    <ComponentThree foo={<ComponentOne />} />
  </div>
)
const ComponentThree = ({ foo }) => <div>{foo}</div>

9

Ich bevorzuge die integrierte React-API:

import React, {cloneElement, Component} from "react";
import PropTypes from "prop-types";

export class Test extends Component {
  render() {
    const {children, wrapper} = this.props;
    return (
      cloneElement(wrapper, {
        ...wrapper.props,
        children
      })
    );
  }
}

Test.propTypes = {
  wrapper: PropTypes.element,
  // ... other props
};

Test.defaultProps = {
  wrapper: <div/>,
  // ... other props
};

dann können Sie das Wrapper-Div durch das ersetzen, was Sie wollen:

<Test wrapper={<span className="LOL"/>}>
  <div>child1</div>
  <div>child2</div>
</Test> 

5

Sie können eine Komponente über übergeben. die Requisiten und rendern es mit Interpolation.

var DivWrapper = React.createClass({
    render: function() {
        return <div>{ this.props.child }</div>;
    }
});

Sie würden dann eine propaufgerufene childKomponente übergeben, die eine React-Komponente wäre.


1
Dies würde dazu führen, dass Komponenten nicht als untergeordnete Elemente, sondern über Attribute übergeben werden. Wenn Sie this.props.childrenwie in einer anderen Antwort vorgeschlagen verwenden, können Sie die Kinder als Kinder anstelle von attrs schreiben.
Ross Allen

1
@ssorallen du hast nicht gesagt, warum man in irgendeiner Weise besser ist ... Wenn du es als Requisite übergibst, kannst du ihm sogar einen Namen geben und propTypes verwenden, um check zu tippen.
Rückkehrea

1
Jedes Element, das Sie in JSX verwenden, ist nur eine Komponente. Wenn sie diesen Ansatz verwenden würden, könnten Sie nicht einmal Ihr kurzes Beispiel schreiben. Es würde werden <div child={this.props.child />.
Ross Allen

1
Schauen Sie sich die JavaScript-Version an (was JSX daraus macht): jsfiddle.net/ssorallen/kvrxcqv8/2 . React.DOM.divVerwendet wie alle Kernkomponenten das childrenArray. Sehen Sie sich an, wie es in Ihrer HelloKomponente verwendet wird. Es werden bereits mehrere untergeordnete Elemente verwendet.
Ross Allen

20
Der Nachteil bei der Fortsetzung einer Diskussion im Chat ist, dass sie nicht für zukünftige Leser archiviert werden.
Ultrafez

3

Spät im Spiel, aber hier ist ein leistungsstarkes HOC-Muster zum Überschreiben einer Komponente, indem sie als Requisite bereitgestellt wird. Es ist einfach und elegant.

Angenommen, es wird MyComponenteine fiktive AKomponente gerendert, aber Sie möchten Ain diesem Beispiel eine benutzerdefinierte Überschreibung von zulassen B, die Aein <div>...</div>einschließt und auch "!" zur Textstütze:

import A from 'fictional-tooltip';

const MyComponent = props => (
  <props.A text="World">Hello</props.A>
);
MyComponent.defaultProps = { A };

const B = props => (
  <div><A {...props} text={props.text + '!'}></div>
);

ReactDOM.render(<MyComponent A={B}/>);

1

Ihre Frage ist eigentlich, wie Sie eine Komponente höherer Ordnung (Higher Order Component, HOC) schreiben. Das Hauptziel der Verwendung von HOC besteht darin, das Einfügen von Kopien zu verhindern. Sie können Ihr HOC als rein funktionale Komponente oder als Klasse schreiben. Hier ein Beispiel:

    class Child extends Component {
    render() {
        return (
            <div>
                Child
            </div>
        );
    }
}

Wenn Sie Ihre übergeordnete Komponente als klassenbasierte Komponente schreiben möchten:

    class Parent extends Component {
    render() {
        return (
            <div>
                {this.props.children}
            </div>
        );
    }
}

Wenn Sie Ihren Elternteil als Funktionskomponente schreiben möchten:

    const Parent=props=>{
    return(
        <div>
            {props.children}
        </div>
    )
}

0

Hier ist ein Beispiel eines übergeordneten Liste react Komponente und whos Requisiten enthalten ein Element reagieren. In diesem Fall wird nur eine einzelne Link- Reaktionskomponente übergeben (wie im dom-Rendering dargestellt).

class Link extends React.Component {
  constructor(props){
    super(props);
  }
  render(){
    return (
      <div>
        <p>{this.props.name}</p>
      </div>
     );
  }
}
class List extends React.Component {
  render(){
   return(
    <div>
       {this.props.element}
       {this.props.element}
    </div>
   );
  }
}

ReactDOM.render(
  <List element = {<Link name = "working"/>}/>,
  document.getElementById('root')
);

0

Ja, Sie können dies mit Requisiten tun. Sie können Daten der Komponente als Objekt wie Requisiten übergeben und dann innerhalb der Komponente eine andere Komponente importieren und dynamisch mit Prpps-Daten binden. Lesen Sie mehr über die Reaktionskomponente


1
Kannst du etwas Code aus dem Link herausarbeiten, den du gepostet hast
Nelles
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.