【问题标题】:Replace <a> with React <Link> in text在文本中将 <a> 替换为 React <Link>
【发布时间】: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 的情况下更改页面时一样@

标签: javascript reactjs react-router jsx


【解决方案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

    【讨论】:

      猜你喜欢
      • 2015-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-12
      • 2011-03-22
      • 2012-01-22
      • 2019-01-16
      相关资源
      最近更新 更多