1

I am trying to develop a web app using react and i have a issue. my component get a 'exists component name' and I try to render this new component inside render function of the current component.

my current component render function

render(){

    let Xxx = null;
    if( this.props.onHex ){
      console.log( this.props.onHex );
      Xxx = <this.props.onHex />
    }

    return(
        <div className="myClass">
            <div className="anotherClass">
               {Xxx}
            </div>
        </div>
    );
  }
}

it not works for me, the console log returns the name of the new component "Unit". when I replace the Xxx = <this.props.onHex /> with this Xxx = <Unit /> it works and render the Unit's render function.

it looks like react not recognise <Unit/> as component. what I am doing wrong please advise.

my Unit code:

    export default class Unit extends Component{

    render(){
        return(
            <div>test</div>
        );
    }
}

UPDATE: when I use const XxxName = Unit; Xxx = <XxxName />; it works for me but I want to be able to render the component from string ( I got this string from json ). I guess I can create all my possible components at this situation inside a file load them into array or something and get them by string, but it's not something that can live with I have a lot of components maybe if I will some how load them from separate folder ( individual file for each component ) it will be half solution. but I still looking how to load component from string.

jsFiddle with another similar issue http://jsfiddle.net/dhjxu5oL/

UPDATE 2: I am not found elegant way to reach my goal (I don't sure if it exists) for now I am using method for each dynamic component for hope that someone will advise me with more elegant solution. check it: React / JSX Dynamic Component Name

newExampleComponent() {
    return <ExampleComponent />;
}

newComponent(type) {
    return this["new" + type + "Component"]();
}
Dennis
  • 704
  • 1
  • 9
  • 25
  • 1
    Is `this.props.onHex` a string or a reference of some kind? – Chris Sep 08 '17 at 13:03
  • You can't pass "component name" `` and expect it to pick the component constructor you have somewhere else. You need to pass a reference to your Unit component like this `` – Yury Tarabanko Sep 08 '17 at 13:14
  • @Chris this is a string. – Dennis Sep 09 '17 at 07:43
  • @YuryTarabanko why not it not sounds so bad for me, what the different between `` and `<$unit />`, this comment actually gave me an idea to use something like `const Xxx = window[ this.props.onHex ]()` because when I use `const Xxx = Unit;` it works. – Dennis Sep 09 '17 at 07:56
  • " what the different between and <$unit />" no difference in this case. But if you do `` it will be desugared to `React.createElement('unit', null)` not `React.createElement(unit, null)`. "gave me an idea to use something like const Xxx = window[ this.props.onHex ]()" this is bad idea because you are polluting global scope with your components. High chances to introduce subtle bugs caused by name collisions. – Yury Tarabanko Sep 09 '17 at 10:57

1 Answers1

1
let Xxx = null;
if( this.props.onHex ){
  const XxxName = this.props.onHex;
  Xxx = <XxxName />;
}

Check this jsfiddle for example


UPDATE:

According to React official docs

You cannot use a general expression as the React element type. If you do want to use a general expression to indicate the type of the element, just assign it to a capitalized variable first. This often comes up when you want to render a different component based on a prop:

So you need to assign this.props.onHex to a CAPITALIZED variable first then you should be able to use it.


UPDATE again

Seems you want to pass a string, not a reference to the component. There is a dirty way to do that

const xxx = this.props.onHex || "";
const XxxComp = eval(xxx);
...
return (<XxxComp />);

I created this codepen for testing

An Nguyen
  • 1,487
  • 10
  • 21
  • 1
    It does not work by using `this.props.onHex` directly. – An Nguyen Sep 08 '17 at 13:07
  • This likely wont work because it seems that OP is treating jsx as some sort of html extension and passing "component name" instead of a reference to the component. – Yury Tarabanko Sep 08 '17 at 13:09
  • @FiriceNguyen, ah right. You should point that out in your answer because as it currently stands, it doesn't really say what it solves. – Chris Sep 08 '17 at 13:10
  • @Chris: yeah, you are right. It's better to have some explanation. I have added more details :) – An Nguyen Sep 08 '17 at 13:14
  • it not works for me, I tried `const XxxName = this.props.onHex; Xxx = ;` not work, I tried `Xxx = ` same .. it creates but not as component – Dennis Sep 08 '17 at 20:13