Dynamic Tag Name in React Jsx

Dynamic tag name in React JSX

No way to do that in-place, just put it in a variable (with first letter capitalised):

const CustomTag = `h${this.props.level}`;

<CustomTag>Hello</CustomTag>

Dynamic tag name in Solid JSX

Solid has a <Dynamic> helper component for that use.

import {Dynamic} from "solid-js/web";

<Dynamic component="div" {...attributes}>
{props.children}
</Dynamic>

Dynamic JSX element/tag names

Regarding dynamic HTML tags:

EDIT:
As the docs suggest, Dynamic types can be used at runtime if first assign to a capitalised variable first:

class Quiz extends React.Component {
constructor(props) {
super(props);
this.state = {
questionText: '',
correctAnswer: [],
assetType: ['DragNDrop', 'MultipleChoice', 'MatchPairs']
}
}
render() {
const ElementNameStartsWithCapitalLetter = this.state.assetType[0];
// ^ -- capital letter here, ensure this works when used in JSX
return <ElementNameStartsWithCapitalLetter />;
}
}

This is due to the fact that User Defined JSX Components Must BE Capitalized.




PREVIOUS SOLUTIONS:

Using React.createElement:

class Quiz extends React.Component{
constructor (props){
super (props);
this.state = {
questionText: '',
correctAnswer: [],
assetType: ['DragNDrop','MultipleChoice','MatchPairs']
}
}
render(){
const { questionText, correctAnswer } = this.state;
{React.createElement(
[this.props.typeIndex],
{...questionText, ...correctAnswer}
);}
}
}

Using conditional rendering:

// Conditional rendering works, but yuck!
// One condition per state works
// <b>but can be unnecessarily verbose</>
getHeader() {
switch(this.state.headerSize){
case 1:
return <h1>{ this.state.headerText }; <h1>
case 2:
return <h2>{ this.state.headerText }<h2>
.
.
.
default:
return null;
}
}

render (){
return { this.getHeader() }; // bound correctly in constructor of course :)
}

Dynamic tag name with JSX and React Native

You shouldn't reference the element by it's name, but directly by class

import {
TouchableNativeFeedback,
TouchableOpacity
} from 'react-native';

const Element = Platform.OS === 'ios' ? TouchableOpacity : TouchableNativeFeedback;

class SomeComponent extends React.Component {

render() {
const { element } = this.props;

return (
<Element style={styles.sectionEntryContainer}>
<View style={styles.sectionDayContainer}>
<LinearGradient
style={styles.gradientStyle}
start={{x: 0, y: 0}} end={{x: 1, y: 0}}
colors={COLOR_MAP[element.item.data.mood].colors}
>
<Text style={styles.sectionDayText}>{ moment(element.item.day, 'D').format('Do') }</Text>
</LinearGradient>
</View>
<View style={styles.sectionDayDescriptionContainer}>
<Text style={styles.sectionDayText}>{ element.item.data.optionalDescription }</Text>
</View>
</Element>
);
}
}

React / JSX Dynamic Component Name

<MyComponent /> compiles to React.createElement(MyComponent, {}), which expects a string (HTML tag) or a function (ReactClass) as first parameter.

You could just store your component class in a variable with a name that starts with an uppercase letter. See HTML tags vs React Components.

var MyComponent = Components[type + "Component"];
return <MyComponent />;

compiles to

var MyComponent = Components[type + "Component"];
return React.createElement(MyComponent, {});

React Dynamic tag name

The problem is when you create the element you are passing a string (data-site value), not a component reference. So it ends up like this:

React.createElement("Fci");

As opposed to:

React.createElement(Fci);

Using a string will create a simple HTML element, not a component with with its own rendered content.

You could create a component map like this:

const componentMap = {
"Fci": Fci,
"Fus": Fus,
"Ssg": Ssg
}

Then from your string you can resolve a component reference:

React.createElement(componentMap[site], {site: site});

Or you could pass a component reference from your Nav:

<button onClick={this.update.bind(this, Ssg, "Ssg"}> SSG </button>

update(component, site, e) {
this.props.site(component, site);
}

pickSite(component, site) {
React.createElement(component, {site: site});
}

ReactJS - Dynamic Component Name with closing tag and children elements

Absolutely there is a way to dynamically set the component at runtime.

Choosing the Type at Runtime

Create a component map object to hold references to the imported components

const components = {
PrivateLayout,
PublicLayout
};

And then do something similar to what you tried by using the connected value to look up in the map the component to assign to the wrapper.

export default function Home() {
const connected = false;
const Layout = connected ? components.PublicLayout : components.PrivateLayout;

return (
<Layout>
{/*here are my child components*/}
</Layout>
);
}


Related Topics



Leave a reply



Submit