动态JSX元素/标签名称 [英] Dynamic JSX element/tag names

查看:86
本文介绍了动态JSX元素/标签名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我只是想知道是否存在使用ReactJS动态渲染元素的最佳实践方法

请考虑以下情形:

(1)参数工厂组件:
一个参数化的工厂组件,其工作是基于字符串参数 来渲染组件 .

 <pre><code>// The following doesn't work
class Quiz extends React.Component{
  constructor (props){
    super (props);
    this.state = {
      questionText: '',
      correctAnswer: [],
      assetType: ['DragNDrop','MultipleChoice','MatchPairs']
    }
  }
  render(){
    const { questionText, correctAnswer } = this.state;
    return <{this.state.assetType[this.props.typeIndex] />;
  }
}
</code></pre>
 

(2)动态HTML标签:
根据整数输入呈现不同的HTML标头标记.为此,我最初尝试使用Template字符串,但不得不求助于条件渲染.

 <pre><code>// No joy with Template strings
render (){
  <{`h${this.state.headerSize}`}>
    {this.state.headerText}
  </ {`h${this.state.headerSize}`}>
}
 

我喜欢使用JSX,能够与动态元素名称保持一致会很好.

我也知道:

 assetType: ['DragNDrop','MultipleChoice','MatchPairs']
 

可以存储为:

 assetType: [<DragNDrop />,<MultipleChoice />, <MatchPairs />]
 

这将起作用.

我与JSX元素数组有关的一个问题是如何将这些JSX元素存储在数据库中?我猜我必须将它们存储为Strings,但是当从数据库中拉回数据库时如何使用它们呢?

有人可以建议解决这些问题的任何可行方法和最佳实践方法吗?

解决方案

关于动态HTML标签:


正如文档所建议的, 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} );} } }

使用条件渲染:

// 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 :)
}

I'm just wanted to know if there is a best practice approach to rendering an element with ReactJS dynamically

Consider these scenarios:

(1) Parameter Factory component:
A parameterised factory component whose job is to render a component based on a string parameter, is there a way of doing so without having to revert to React.createElement?

<pre><code>// The following doesn't work
class Quiz extends React.Component{
  constructor (props){
    super (props);
    this.state = {
      questionText: '',
      correctAnswer: [],
      assetType: ['DragNDrop','MultipleChoice','MatchPairs']
    }
  }
  render(){
    const { questionText, correctAnswer } = this.state;
    return <{this.state.assetType[this.props.typeIndex] />;
  }
}
</code></pre>

(2)Dynamic HTML tags:
Render a different HTML header tag based on an integer input. For this, I initially tried to use Template strings but had to resort to conditional rendering.

<pre><code>// No joy with Template strings
render (){
  <{`h${this.state.headerSize}`}>
    {this.state.headerText}
  </ {`h${this.state.headerSize}`}>
}

I like using JSX, and it would be nice to be able to use dynamic element names with it for consistency.

I'm also aware that:

assetType: ['DragNDrop','MultipleChoice','MatchPairs']

can be stored as:

assetType: [<DragNDrop />,<MultipleChoice />, <MatchPairs />]

which will work.

One issue I have with the array of JSX elements is how to store the these JSX elements in a DB? I'm guessing I'd have to store them as Strings but then how to use them when pull backed form the DB?

Can anyone suggest any working and best practice approaches to these issues?

解决方案

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 :)
}

这篇关于动态JSX元素/标签名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆