JSX组件+ dangerouslySetInnerHTML?

时间:2017-11-17 04:42:24

标签: javascript regex reactjs react-dom

所以我在实施这种情况时遇到了麻烦:

从后端服务器,我正在接收一个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标签时,该组件实际上增加了创建新子窗口的功能。

我认为这是你需要在Regex上实现的东西,但我没有任何想法从哪里开始。

2 个答案:

答案 0 :(得分:1)

您可以使用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>
        )
    }
}

从那里,您只需将标签包装在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提供了有关正则表达式的更多详细信息。

答案 1 :(得分:1)

不幸的是,我从未真正使用过JavaScript,这就是为什么我的回答只关注这个问题的正则表达式部分。 (尽管如此,我已经尝试了一个尝试!)

如果我理解正确,您希望将<a href="someLink">someTitle</a>标记替换为<ModalLink href={'someLink'}>someTitle</ModalLink>,方式someLinksomeTitle也将位于ModalLink标记中 - 如果我以错误的方式理解这一点,请纠正我

现在看看这个正则表达式模式

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

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

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

<ModalLink href={'$2'}> {$3} </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

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

编辑:我现在已经尝试使用在线编译器来使用JavaScript方法用标签替换标签,并且在使用上述正则表达式的方法时似乎工作正常:

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

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

您也可以尝试this online here