-
Notifications
You must be signed in to change notification settings - Fork 46.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to render component from name string #3365
Comments
Simple fix: just use |
@spicyj I don't think that's what he is asking. I think he wants to be able to create a React element from a dynamically acquired name (string). What he is looking for is:
instead of what he has ( |
|
@spicyj EDIT: You're correct. |
@spicyj @JSFB Both of those suggestions arrive at the same outcome. Neither of them are supporting the ability to dynamically generate name strings which reference existing components. I wanted to store some ID value in a component prop and then use the name string to render the component. What I am looking for is something almost like eval() or running
Updated fiddle with easy testing: http://jsfiddle.net/q3zwtosw/ |
As you probably know, it's best practice not to use
The key is to use a capitalized variable name ( |
I am aware of evils of eval / window lookups, I just assumed/hoped React would support something like a secure scoped reference method as part of JSX transpiling. One could easily implement an immutable scoped object of valid component names and then compare strings to ensure that nothing malicious was going to be passed to the lookup method. It would greatly simplify dynamic component calls by not requiring massive switch or else if statements in front of render return statements. |
Maybe you can do something like
which isn't a large overhead but is more reasonable than using globals. React tries to be simple and get out of your way instead of adding a lot of magic – you can then build whatever you want on top, just as you can in JS without React. |
@charliegeiger89: what is your final solution for this issue? I am having the same problem as yours. I have tried window[myStringVal], however, it fails somehow in Firefox. var allMyComponents = {}; var Child = React.createClass(...); // ... |
Came across this issue today, from a bit different point of view: configuration. I'm creating an embeddable element that can receive configuration options - one of them being what react class to use when rendering. Example:
I want to be able to pass a There are no problems if the react class object gets passed in as Currently I'm using |
React doesn't have a global registry so that won't ever be built-in functionality. You could have your own registry and just make sure each class registers in that, then you could access that inside // DifferentListElement.js.jsx
var DifferentListElement = React.creaceClass({});
ReactComponentRegistry.set('DifferentListElement', DifferentListElement);
// EmbeddableList.js.jsx
var EmbeddableList = React.creaceClass({
render() {
var ListElement = ReactComponentRegistry.get(this.props.listElementClass)
return <Whatever><ListElement>...
}
}); This is essentially what Ben described above, but with a registry object. Either way it would require a different global object be available. The other thing is that you may be setting
|
I came twice in a situation that I needed a dynamic use of the proper component. A suggestion below: The React team could create a helper function, for example: React.getComponentByName(name: string), that returns the component that has the same name as the input string:
In that way, we can easily implement the following use case of rendering the proper component based on props received:
Then, in JSX:
|
@af7 If that's what you want then you need to provide the mapping yourself, there is nothing React can do for you here. React works with regular classes and classes are not magically registered with React. import MyComponent1 from './MyComponent1.js';
import MyComponent2 from './MyComponent2.js';
import MyComponent3 from './MyComponent3.js';
const myComponentsList = [
MyComponent1,
MyComponent2,
MyComponent3
];
const myComponentsListByName = {
MyComponent1: MyComponent1,
MyComponent2: MyComponent2,
MyComponent3: MyComponent3
};
/* es6 syntax */
const myComponentsListByName = {
MyComponent1,
MyComponent2,
MyComponent3
}; |
What @syranide said. Then in render you can do: // Needs to start with a capital letter
var Type = myComponentsList[this.props.componentId];
...
<Type /> |
If you can live with having all your components in one module, then this works pretty well:
|
From @rmoskal said, I've been able to put something together. I'm also using I created a
The important part then is to use Then in your parent module you can do :
I pass "ProductColor" in my This is the best solution I found so far, also for some reason |
@afilp, this solution is not favorable to Tree Shaking |
I seem to be unable to render components using name strings. I wanted to be able to dynamically generate component name strings which have existing corresponding components that can be rendered.
Fiddle: http://jsfiddle.net/dhjxu5oL/
Instead of referencing the existing component and rendering it, React is rendering a custom element tag that is all lower case.
Very basic code that is failing:
The text was updated successfully, but these errors were encountered: