Dynamic tag name in jsx and React

点点圈 提交于 2019-11-26 05:19:40

问题


I try to write a React component. for html heading tags(h1,h2,h3,etc...), where the heading priority dynamically changing based on the priority we have defined in the props.

Here what I try to do.

<h{this.props.priority}>Hello</h{this.props.priority}>

expected output:

<h1>Hello</h1>

This is not working. Is there any possible method to do this?


回答1:


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>



回答2:


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.




回答3:


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>



回答4:


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



来源:https://stackoverflow.com/questions/33471880/dynamic-tag-name-in-jsx-and-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!