在文本中将 <a> 替换为 React <Link>

Posted

技术标签:

【中文标题】在文本中将 <a> 替换为 React <Link>【英文标题】:Replace <a> with React <Link> in text 【发布时间】:2019-07-14 14:36:16 【问题描述】:

在我的 React 应用程序中,我从另一台服务器(***)获取了一些 html,并且 - 在本文中 - 想要用 react-router 链接替换所有链接。

我想出的是以下代码:

// Parse HTML with javascript DOM Parser
let parser = new DOMParser();
let el = parser.parseFromString('<div>' + html + '</div>', 'text/html');

// Replace links with react-router links
el.querySelectorAll('a').forEach(a => 
  let to = a.getAttribute('href');
  let text = a.innerText;
  let link = <Link to=to>text</Link>;
  a.replaceWith(link);
);
this.setState(
  html: el.innerHTML
)

然后在render() 之后,我将其插入到页面中使用

<div dangerouslySetInnerHTML=__html: this.state.html />

问题在于 React JSX 不是原生 JavaScript 元素,因此无法与 replaceWith 一起使用。我还假设这样的Link 对象不能存储为文本,然后使用dangerouslySetInnerHTML 恢复。

那么:执行此方法的最佳方法是什么?我想保留链接周围的所有各种元素,所以我不能简单地遍历render()中的链接

【问题讨论】:

您可以创建利用历史 API 的链接,以便“以编程方式”影响 react-router,就像您希望 javascript 的任何部分在不使用 @987654328 的情况下更改页面时一样@ 【参考方案1】:

您可以利用html-react-parser 的功能

import parse,  domToReact  from 'html-react-parser';
import  Link  from 'react-router-dom';    

function parseWithLinks(text) 
  const options = 
    replace: ( name, attribs, children ) => 
      if (name === 'a' && attribs.href) 
        return <Link to=attribs.href>domToReact(children)</Link>;
      
    
  ;
      
  return parse(text, options);

然后像这样使用它:

const textWithRouterLinks = parseWithLinks('<a href="/home">Home page</a>');

【讨论】:

【参考方案2】:

嗯,你真的需要使用Link 选项 1:

import  renderToString  from 'react-dom/server';
el.querySelectorAll('a').forEach(a => 
  let to = a.getAttribute('href');
  let text = a.innerText;
  const link = renderToString(<Link to=to>text</Link>);
  a.replaceWith(link);
);

选项 2:使用html-react-parser

【讨论】:

智能移动。比解析好得多 这真的有效吗?由于 renderToString 被设计为在服务器上使用,因此在使用 this 时,可能不会为 Link 组件正确设置相关的 onClick 处理程序等【参考方案3】:

你不能像这样渲染&lt;Link&gt;。 相反,您可以尝试另一种方式:

el.querySelectorAll('a').forEach((a) => 
    a.addEventListener('click', (event) => 
       event.preventDefault()
       const href = a.getAttribute('href');
       // use React Router to link manually to href
    )
)

当点击&lt;a&gt;你手动路由。

见Programmatically navigate using react router

【讨论】:

以上是关于在文本中将 <a> 替换为 React <Link>的主要内容,如果未能解决你的问题,请参考以下文章

如何在本机反应中将 <Text> 文本设置为大写

React Uncaught TypeError:无法读取未定义的属性“替换”

如何在React native中将屏幕分为三个具有不同文本内容的部分

UBB 代码 [textarea] - 不要在标签 [textarea][/textarea] 中将 \n 替换为 <br>

我用换行符替换所有标签`<br>`

在 C# 中将字符串中的“\\”替换为“\”