Dynamisches Rendern einer React-Komponente

78

In React JSX scheint es nicht möglich zu sein, Folgendes zu tun:

render: function() {
  return (
    <{this.props.component.slug} className='text'>
      {this.props.component.value}
    </{this.props.component.slug}>
  );
}

Ich erhalte einen Analysefehler: Unerwartetes Token {. Kann React damit nicht umgehen?

Ich entwerfe diese Komponente so, dass die darin gespeicherten Werte unter der Haube this.props.component.sluggültige HTML-Elemente (h1, p usw.) enthalten. Gibt es eine Möglichkeit, diese Arbeit zu machen?

eriklharper
quelle

Antworten:

96

Sie sollten keine Komponenten in geschweiften Klammern setzen:

var Hello = React.createClass({
    render: function() {
        return <this.props.component.slug className='text'>
            {this.props.component.value}
        </this.props.component.slug>;
    }
});

React.renderComponent(<Hello component={{slug:React.DOM.div, value:'This is my header'}} />, document.body);

Hier ist eine funktionierende Geige: http://jsfiddle.net/kb3gN/6668/

Außerdem finden Sie JSX Compiler hilfreich zum Debuggen dieser Art von Fehlern: http://facebook.github.io/react/jsx-compiler.html

Nilgun
quelle
16
Ein Problem, das ich gerade herausgearbeitet habe, ist, dass Sie einen Punkt var page; <page></page>var page = { component: component }; <page.component></page.component>
angeben
5
React behandelt Variablen als benutzerdefinierte Elemente, wenn sie groß geschrieben sind oder eine Punktnotation haben, andernfalls HTML-Elemente. Dh <Seite> </ Seite> funktioniert auch
bebbi
musste React.DOM.div durch 'div' ersetzen, damit es funktioniert
galki
3
Beachten Sie, dass Ihre Variable die Komponente selbst und nicht nur den Namen der Komponente als Zeichenfolge enthalten sollte .
Totymedli
22

Wie bereits erwähnt, sollte der Bauteil nicht in geschweifte Klammern gewickelt werden.

Wenn Sie es in einer Variablen speichern möchten, stellen Sie sicher, dass es mit einem Großbuchstaben beginnt.

Hier ist ein Beispiel:

var Home = React.createClass({
  render: function() {
    return (
      <div>
        <h3>This is an input</h3>
        <CustomComponent inputType="input" />
        <h3>This is a text area</h3>
        <CustomComponent inputType="textarea" />
      </div>
    );
  }
});

var CustomComponent = React.createClass({
  render: function() {
    // make sure this var starts with a capital letter
    var InputType = this.props.inputType;
    return <InputType />;
  }
});

React.render(<Home />, document.getElementById('container'));

Hier ist eine funktionierende Geige: https://jsfiddle.net/janklimo/yc3qcd0u/

Jan Klimo
quelle
Du rockst !! Der Variablenname beginnt mit einem Großbuchstaben. Das ist komisch, aber es ist was es ist.
Aftab Naveed
5

Wenn Sie beabsichtigen, die tatsächlich gerenderte Komponente einzufügen, können Sie Folgendes tun, was zum Testen sehr praktisch ist oder aus welchem ​​Grund Sie Komponenten zum Rendern dynamisch einfügen möchten.

var MyComponentF=function(ChildComponent){
    var MyComponent = React.createClass({
        getInitialState: function () {
            return {
            };
        },
        componentDidMount: function () {
        },
        render: function () {
            return (
                <div className="MyComponent">
                    <ChildComponent></ChildComponent>
                </div>
            );
        }
    });
    return MyComponent;
};

var OtherComponentF=function(){
    var OtherComponent = React.createClass({
        getInitialState: function () {
            return {
            };
        },
        componentDidMount: function () {
        },
        render: function () {
            return (
                <div className="OtherComponent">
                    OtherComponent
                </div>
            );
        }
    });
    return OtherComponent;
};

var AnotherComponentF=function(){
    var AnotherComponent = React.createClass({
        getInitialState: function () {
            return {
            };
        },
        componentDidMount: function () {
        },
        render: function () {
            return (
                <div className="AnotherComponent">
                    AnotherComponent
                </div>
            );
        }
    });
    return AnotherComponent;
};

$(document).ready(function () {
    var appComponent = MyComponentF(OtherComponentF());

    // OR
    var appComponent = MyComponentF(AnotherComponentF());

    // Results will differ depending on injected component.

    ReactDOM.render(React.createElement(appComponent), document.getElementById("app-container"));
});
Gudlaugur Egilsson
quelle
4

Edit : Vielleicht hast du vergessen, /** @jsx React.DOM */am Anfang von js hinzuzufügen?

Sie können jedoch verwenden React.DOM:

render: function() {
  return React.DOM[this.props.component.slug](null, this.props.component.value);
}

http://jsbin.com/rerehutena/2/edit?html,js,output

Ich bin kein React-Experte, aber ich denke, jede Komponente sollte am Anfang mit einem bestimmten Tag erstellt werden. Es könnte also selbst einen klaren Zweck darstellen.

fankt
quelle
0

Die Lösung für mich bestand darin, die importierte Komponente einer Variablen (mit CapitalCase) zuzuweisen und diese Variable dann zu rendern.

Beispiel:

import React, { Component } from 'react';
import FooComponent from './foo-component';
import BarComponent from './bar-component';

class MyComponent extends Component {
    components = {
        foo: FooComponent,
        bar: BarComponent
    };

        //this is the most important step
       const TagName = this.components.foo;

    render() {
       return <TagName />
    }
}
export default MyComponent;
Juanma Menendez
quelle
Die Lösung funktioniert nicht!
Nikhil Patil