【问题标题】:Dynamically rendered Tag is always lowercase动态渲染的标签总是小写的
【发布时间】:2018-08-20 16:11:53
【问题描述】:

我正在尝试输出一些 svg 并从列表中输出它们,这是我的渲染方法:

render() {

        const renderTag = () => {
            const Tag = this.props.id
            return(<Tag />)
        } 

        return (
            <div key={this.props.name} className="social-box">
                <a className={this.props.id + "-link"}> 
                    {renderTag()}
                </a>
            </div>
        )
    }

但是,DOM 节点始终是小写的,即 &lt;facebook&gt; 而不是 &lt;Facebook&gt; this.props.id 在控制台上正确呈现为 Facebook。谁能告诉我为什么反应或浏览器错误地呈现为小写,因此不是组件,以及如何修复?

【问题讨论】:

  • 您的代码似乎没有错,接受您在 render 中声明的函数,每次调用 render 时都会重新创建该函数。你能制作一个可重现的问题演示吗
  • @ShubhamKhatri 这样做没有错,这会导致这个问题吗?事实上,看看我的回答,这很可能是造成这种情况的原因。
  • @SamPettersson,我什么时候说过将renderTag 移到render 之外会解决问题。我只是要求其他人提供他的问题的可重现演示,因为即使 React 将标签转换为小写,OP 问题是组件没有被渲染

标签: javascript reactjs jsx


【解决方案1】:

感谢您的提问和回答;除了Dynamic tag name in jsx and React 中给出的答案之外,它们还帮助我在我的上下文中找到了解决方案(在安装了gatsby-plugin-react-svg 的 Gatsby 中制作了一个功能组件):

import React from "react"
import FirstIcon from "../svgs/first-icon.inline.svg"
import SecondIcon from "../svgs/second-icon.inline.svg"
import ThirdIcon from "../svgs/third-icon.inline.svg"

const MyComponent = () => {
  const sections = [
    { heading: "First Section", icon: () => <FirstIcon /> },
    { heading: "Second Section", icon: () => <SecondIcon /> },
    { heading: "Third Section", icon: () => <ThirdIcon /> },
  ]

  return (
    <>
      {sections.map((item, index) => {
        const Icon = item.icon
        return (
          <section key={index}>
            <Icon />
            <h2>{item.heading}</h2>
          </section>
        )
      })}
    </>
  )
}

export default MyComponent

因为我的是 Gatsby 项目,所以我使用了上面提到的插件,但它本身使用 svg-react-loader 处理 svgs,所以基本原理应该适用于使用这个包的任何 React 项目。

【讨论】:

    【解决方案2】:

    我最终找到了答案。 @TomMendelson 几乎有了答案,但还需要进一步充实。

    @ShubhamKhatri 建议的在 render 方法之外创建组件的函数实际上完成了这项工作。这是最终代码:

    import React from 'react';
    import Facebook from './svg/Facebook';
    import LinkedIn from './svg/LinkedIn';
    import Twitter from './svg/Twitter';
    import Pinterest from './svg/Pinterest';
    
    class SocialMediaBox extends React.Component {
    
        renderElement(item) {
            const Components = {
                'Facebook': Facebook,
                'Twitter': Twitter,
                'Pinterest': Pinterest,
                'LinkedIn': LinkedIn 
            }
            return React.createElement(Components[item], item);
        }
    
        render() {
    
            const Element = this.renderElement(this.props.id)
    
            return 
            (
                <div>
                    {Element}
                </div>
            )
        }
    }
    
    export default SocialMediaBox;
    

    【讨论】:

      【解决方案3】:

      我建议你看看this article 关于动态组件。

      文章中最相关的例子:

      import React, { Component } from 'react';
      import FooComponent from './foo-component';
      import BarComponent from './bar-component';
      class MyComponent extends Component {
          components = {
              foo: FooComponent,
              bar: BarComponent
          };
          render() {
             const TagName = this.components[this.props.tag || 'foo'];
             return <TagName />
          }
      }
      export default MyComponent;
      

      您很可能只有有限数量的可以渲染的组件,因此您可以创建一个字典,其中包含组件本身的键(组件名称)(如示例中所示)并以这种方式使用它:

      import Facebook from './FaceBook';
      import Twitter from './Twitter';
      
      const components = {
         facebook: Facebook,
         twitter: Twitter
      };
          render() {
                  return <div key={this.props.name} className="social-box">
                          <a className={this.props.id + "-link"}> 
                              <components[this.props.id] />
                          </a>                
      </div>;
      
          }
      

      【讨论】:

      • 我在万不得已来到这里之前发现了这篇文章。我实现了这种方法,但是它,你的代码在这里不起作用。
      • 我为此案例创建了一个测试在线应用程序:stackblitz.com/edit/react-fwfeez 如上所述工作
      【解决方案4】:

      这是 React 的技术实现,所有标签在这一行 here 上都是小写的,AFAIK 不可能呈现非小写的标签,这是设计使然。

      阅读更多here

      【讨论】:

      • 这肯定回答了为什么会发生这种情况
      猜你喜欢
      • 2020-04-09
      • 2014-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-13
      • 2020-09-23
      • 1970-01-01
      相关资源
      最近更新 更多