Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic tag name in jsx and React

Tags:

reactjs

jsx

People also ask

How do I add a dynamic tag in React?

You can simply pass the dynamic tag name as the first argument to the React. createElement() method (as it accepts a string tag name). For example: const type = (someCondition) ?

Can we use script tag in JSX?

Import 'ScriptTag' component: Import the built-in 'ScriptTag' component from the react-script-tag library at the top of the file where we want to add the script tag. Now call the <ScriptTag> component inside our App component. This is a self-closing JSX component.

How do you pass a tag as a prop in React?

You can simply use {} to cause JSX to parse the parameter. The only limitation is the same as for every JSX element: It must return only one root element.

What is dynamic component in React?

As the building blocks of React applications, components are dynamic, in that they can describe a template of HTML and fill in variable data. This lesson builds a real example of a blogging application to illustrate dynamic components.


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

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

<CustomTag>Hello</CustomTag>

If you're using TypeScript, you'll have seen an error like this:

Type '{ children: string; }' has no properties in common with type 'IntrinsicAttributes'.ts(2559)

TypeScript does not know that CustomTag is a valid HTML tag name and throws an unhelpful error.

To fix, cast CustomTag as keyof JSX.IntrinsicElements!

const CustomTag = `h${this.props.priority}` as keyof JSX.IntrinsicElements;

<CustomTag>Hello</CustomTag>

For completeness, if you want to use a dynamic name, you can also directly call React.createElement instead of using JSX:

React.createElement(`h${this.props.priority}`, null, 'Hello')

This avoids having to create a new variable or component.

With props:

React.createElement(
  `h${this.props.priority}`,
  {
    foo: 'bar',
  },
  'Hello'
)

From the docs:

Create and return a new React element of the given type. The type argument can be either a tag name string (such as 'div' or 'span'), or a React component type (a class or a function).

Code written with JSX will be converted to use React.createElement(). You will not typically invoke React.createElement() directly if you are using JSX. See React Without JSX to learn more.


All the other answers are working fine but I would add some extra, because by doing this:

  1. It is a bit safer. Even if your type-checking is failing you still return a proper component.
  2. It is more declarative. Anybody by looking at this component can see what it could return.
  3. Its is more flexible for example instead of 'h1', 'h2', ... for type of your Heading you can have some other abstract concepts 'sm', 'lg' or 'primary', 'secondary'

The Heading component:

import React from 'react';

const elements = {
  h1: 'h1',
  h2: 'h2',
  h3: 'h3',
  h4: 'h4',
  h5: 'h5',
  h6: 'h6',
};

function Heading({ type, children, ...props }) {    
  return React.createElement(
    elements[type] || elements.h1, 
    props, 
    children
  );
}

Heading.defaultProps = {
  type: 'h1',
};

export default Heading;

Which you can use it like

<Heading type="h1">Some Heading</Heading>

or you can have a different abstract concept, for example you can define a size props like:

import React from 'react';

const elements = {
  xl: 'h1',
  lg: 'h2',
  rg: 'h3',
  sm: 'h4',
  xs: 'h5',
  xxs: 'h6',
};

function Heading({ size, children }) {
  return React.createElement(
    elements[size] || elements.rg, 
    props, 
    children
  );
}

Heading.defaultProps = {
  size: 'rg',
};

export default Heading;

Which you can use it like

<Heading size="sm">Some Heading</Heading>

In the instance of dynamic headings (h1, h2...), a component could return React.createElement (mentioned above by Felix) like so.

const Heading = ({level, children, ...props}) => {
    return React.createElement(`h${level}`, props , children)
}

For composability, both props and children are passed.

See Example