Reputation: 2134
I'm a real beginner in javascript / React...but I'm trying to set-up a tag based on a string value. Why does widget1 fail to get instantiated? (I get an uncaught ReferenceError: FooA is not defined error) What difference does importing the react component make, versus defining it in the same file?
import React, {Component} from "react";
import ReactDOM from "react-dom";
// Assume FooA and FooB have identical definitions
import FooA from './fooa.jsx'
class FooB extends Component {
render() {
return(<p>Hello A</p>);
}
};
class Splash extends Component {
render() {
var widget1 = eval('new ' + "FooA")
var widget2 = eval('new ' + "FooB")
return (
<div>
{(widget1.render())}
{(widget2.render())}
</div>
)
};
}
ReactDOM.render(<Splash/>, container);
I am passing this through webpack to get a single .js file.
Is there a better way to achieve this?
Upvotes: 2
Views: 76
Reputation: 35787
You're coming at this problem from the wrong angle. If you want to make a component able to render other components in a generic, reusable way, there's three approaches you can take:
class Splash extends Component {
render() {
let heading = this.props.heading;
// These have to start with a capital letter, otherwise
// JSX assumes 'widget1' is a normal HTML element.
let Widget1 = this.props.widget1;
let Widget2 = this.props.widget2;
return (
<div>
<h1>{heading}</h1>
<Widget1 />
<Widget2 />
</div>
)
};
}
// This can then be used like so:
<Splash heading="My Generic Splash" widget1={FooA} widget2={FooB} />
class Splash extends Component {
render() {
let heading = this.props.heading;
let widget1 = this.props.widget1;
let widget2 = this.props.widget2;
return (
<div>
<h1>{heading}</h1>
{widget1}
{widget2}
</div>
)
};
}
// This can then be used like so:
let fooA = <FooA />;
<Splash heading="My Generic Splash" widget1={fooA} widget2={<FooB />} />
class Splash extends Component {
render() {
let heading = this.props.heading;
return (
<div>
<h1>{heading}</h1>
{this.props.children}
</div>
)
};
}
// This can then be used like so:
<Splash heading="My Generic Splash">
<FooA />
<FooB />
</Splash>
Upvotes: 1
Reputation: 3866
You dont have to instantiate Components, React does that for you.
Your Splash component should look like this:
class Splash extends Component {
render() {
return (
<div>
<FooA />
<FooB />
</div>
)
};
}
Now lets supouse you want to have some logic to determine which component must be rendered:
class Splash extends Component {
let comp = (<FooA />);
if(some condition)
comp = (<FooB />);
render() {
return (
<div>
{comp}
</div>
)
};
}
Now let supouse you want just to parametrize the text:
class FooA extends Component {
render() {
return(<p>this.props.textToShow</p>);
}
};
class Splash extends Component {
let text = 'whatever text you want to show';
render() {
return (
<div>
<FooA textToShow={text}/>
</div>
)
};
}
You can pass as a prop other components as well:
class FooA extends Component {
render() {
return(
<p>Some text</p>
{this.props.child}
);
}
};
class FooAChild extends Component {
render() {
return(
<p>I am a child</p>
);
}
};
class Splash extends Component {
let child = (<FooAChild />);
render() {
return (
<div>
<FooA child={child}/>
</div>
)
};
}
Upvotes: 1