Using Dynamic Element Names With The JSX Transpiler In ReactJS
When I first started using JSX with ReactJS, I knew that you could use native HTML elements, like <a> and <span>, as well as React Components, like <List> and <ListItem>; but, it didn't occur to me that JSX element names were dynamic in a more general sense. Mostly by trial-and-error, I discovered that a JSX element could be defined by any variable that didn't look like a native HTML element.
The JSX transpiler, in ReactJS, uses upper-case and lower-case convention to distinguish between HTML elements and React components; React components are upper-case and HTML elements are lower-case. But, if you look at the interactive JSX compiler, I think the breakdown can be worded a bit differently: lower-case values become inline strings and everything else becomes a variable reference.
Once I realized that things like "<div>" and "<span>" just compiled down to React.createElement("div") calls, it made sense that the "div" argument could be replaced with a variable that contained a string that represented an element name.
To see this in action, I've created a simple ReactJS component that cycles through a list of HTML element types. And, as it cycles through, the current element type is stored in the component state and used to render the component element:
As you can see, every second, I'm cycling through to the next HTML tag using a setInterval(). Since I am storing the current tag using setState(), ReactJS knows to re-render the current component, which will re-render the component element using the dynamic tag name. And, when we run this code, we get the following output:
I was using this functionality in my previous post on attaching dynamic event handlers to proxied child elements, in ReactJS. In that particular post, the functionality was used as a means to drive home the very dynamic nature of event bindings. But, I could definitely see a use-case for this level of dynamic tag generation in a real app; and, it's good to know that it's possible.
Want to use code from this post? Check out the license.
Huh, somehow I missed this and went with the cumbersome React.createElement syntax: https://gitlab.com/vanity/vanity/blob/master/src/scripts/components/VanityApp.jsx#L55
Thanks for the tip :)
Ah, I see - it took me a minute to figure out what you meant. You were using React.createElement() so that you could pass "elementName" dynamically. Ultimately, that is what the JSX compiles down to; so, you were on the money - this is just an alternate syntax.
How would you add start and stop timers to cycling? For example, add two buttons that will start and stop the cycling of the tags. I've been playing around with it with no luck.
I forgot to mention that. If you have the buttons in a different component, use a mixin to have the timer functions which could be shared with both components.