JSX 组件 + dangerouslySetInnerHTML?

JSX Component + dangerouslySetInnerHTML?

所以我在实现这个场景时遇到了问题:

我从后端服务器接收到一个 html 字符串,如下所示:

<ul><li><strong>Title1</strong> <br/> <a class=\"title1" href="title1-link">Title 1</a></li><li><strong>Title2</strong> <a class="title2" href="/title2-link">Title 2</a>

一般情况下,只要使用dangerouslySetInnerHTML就可以了。

但是,在 html 中的 a href 标签周围,我需要像这样将它们包装在组件中:

<ModalLink href={'title'}>
    {Title}
</ModalLink>

这是因为在包装 a 标签时,该组件实际上添加了创建新子项的功能 window。

我认为这是您需要在 Regex 上实现的东西,但我完全不知道从哪里开始。

您可以使用正则表达式从 html 字符串中解构并提取必要的值,然后使用 JSX 而不是 dangerouslySetInnerHtml。此组件显示如何呈现示例 html 字符串。

import React, { Component } from 'react'

export default class App extends Component {
    render() {
        const html = `<ul><li><strong>Title1</strong><br/><a class="title1" href="/title1-link">Title 1</a></li><li><strong>Title2</strong><br/><a class="title2" href="/title2-link">Title 2</a></li></ul>`

        return (
            <div>
                <ul>
                {html.match(/(<li>.*?<\/li>)/g).map( li => {
                    const title =  li.match(/<strong>(.*?)<\/strong>/)[1]
                    const aTag = li.match(/<a.*?\/a>/)[0]
                    const aClass = aTag.match(/class="(.*?)"/)[1]
                    const href = aTag.match(/href="(.*?)"/)[1]
                    const aText = aTag.match(/>(.*?)</)[1]
                    return (
                        <li>
                            <strong>{title}</strong>
                            <br/>
                            <a className={aClass} href={href}>{aText}</a>
                        </li>
                    )
                })}
                </ul>
            </div>
        )
    }
}

从那里您可以简单地将 a 标签包装在您的 ModalLink 组件中。我不确定这正是您想要的方式,但这是一个示例。

return ( 
    <li>
        <strong>{title}</strong>
        <br/>
        <ModalLink href={href}>
            <a className={aClass} href={href}>{aText}</a>
        </ModalLink>
    </li>
)

html.match(/(<li>.*?<\/li>)/g) 匹配数组中 html 字符串中的每个 <li>...</li>,然后可以进行映射。然后我使用捕获(括号内的部分)从每个 <li>...</li> 中提取标题、href 等,然后可以在 JSX 中使用它们。 This answer 提供了有关所用正则表达式的更多详细信息。

不幸的是,我从来没有真正使用过 JavaScript,这就是为什么我的回答将只关注这个问题的正则表达式部分。 (不过,我在底部添加了一个尝试!)

如果我理解正确的话,您想用 <ModalLink href={'someLink'}>someTitle</ModalLink> 替换 <a href="someLink">someTitle</a> 标签,这样 someLinksomeTitle 就会出现在 ModalLink 标签中, 也 - 如果我以错误的方式理解这一点,请纠正我

现在看看这里的正则表达式模式

<a [^<]+?href\s*=\s*("|')(.*?)>(.*?)<\/a>

它将与任何以 <a 开头的标签匹配,并匹配所有字符,直到找到 href(在 href 和等式标记之间有任意数量的空格)。然后它将搜索 ''"" 引号之间的字符串并捕获它以便稍后使用。它再次匹配,直到它找到标签 > 的结尾,并捕获该结尾和结束标签 <\a>.

之间的任何内容

如果您现在使用某种方法替换给定字符串中匹配的正则表达式(很抱歉,我不熟悉它在 JavaScript[=56= 中的工作方式]) 并用这个模式替换它

<ModalLink href={''}> {} </ModalLink>

对于您收到的示例 html 字符串,您将得到这样的结果:

<ul><li><strong>Title1</strong> <br/> <ModalLink href={'title1-link'}> {Title 1} </ModalLink></li><li><strong>Title2</strong> <ModalLink href={'/title2-link'}> {Title 2} </ModalLink>

替换模式的 $2 和 $3 部分是前面提到的捕获部分的占位符,如您所见,它们将被它们替换。 (他们正在捕获第 2 组和第 3 组,而不是从第 1 组开始,因为我已经将引号捕获为捕获第 1 组)

您可以尝试我提供的模式 here

虽然您可以在 window 的上部查看和编辑正则表达式和输入的字符串,但可以在下部找到替换模式及其结果。


编辑:我现在已经尽力使用在线编译器使用 JavaScript 方法将标签替换为标签,当将此方法与上述正则表达式一起使用时,它似乎工作正常:

var regexMatch = html.replace(/<a [^<>]+?href\s*=\s*("|')(.*?)[^<>]*?>(.*?)<\/a>/g, "<ModalLink href={''}> {} </ModalLink>");

在这种情况下,html 当然应该是要替换 <a> 标签的 html 字符串。

你也可以试试this online here.