You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React TypeScript识别文本URL并转为可点击链接实现方法

React TypeScript 实现聊天消息URL自动转可点击链接

核心实现逻辑

不需要在useEffect中提前遍历修改聊天列表状态,直接在单条消息渲染阶段做文本拆分解析即可,避免不必要的状态更新和重渲染。

1. 修正URL匹配正则

原有正则缺少全局匹配标识g,无法识别单条消息内的多个URL,修正后的正则如下:

const urlRegex = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/g;

2. 编写文本解析工具函数

该函数会将原始消息字符串拆分为普通文本、URL两类片段,方便后续分别渲染:

// 可放在组件外部或公共工具文件中
const parseMessageContent = (content: string) => {
  const fragments: Array<{ type: 'text' | 'link'; value: string }> = [];
  // 无匹配直接返回原文本
  if (!urlRegex.test(content)) {
    return [{ type: 'text', value: content }];
  }
  // 重置正则匹配指针,避免连续匹配错位
  urlRegex.lastIndex = 0;
  let lastEndIndex = 0;
  let matchResult: RegExpExecArray | null;

  while ((matchResult = urlRegex.exec(content)) !== null) {
    // 插入URL之前的普通文本
    if (matchResult.index > lastEndIndex) {
      fragments.push({
        type: 'text',
        value: content.slice(lastEndIndex, matchResult.index)
      });
    }
    // 插入匹配到的URL片段
    fragments.push({
      type: 'link',
      value: matchResult[0]
    });
    lastEndIndex = matchResult.index + matchResult[0].length;
  }
  // 插入末尾剩余的普通文本
  if (lastEndIndex < content.length) {
    fragments.push({
      type: 'text',
      value: content.slice(lastEndIndex)
    });
  }
  return fragments;
};

3. 修改消息渲染逻辑

替换原有直接输出message.message的代码,遍历解析后的片段分别渲染:

{chat.map((messageItem: IMessage, index) => {
  return (
    <Paper
      key={index}
      style={{
        backgroundColor: "#6096ba",
        padding: "5px",
        borderRadius: "30px",
      }}
      elevation={3}
    >
      <p style={{ maxWidth: "20ch", color: "white", wordBreak: "break-all" }}>
        {parseMessageContent(messageItem.message).map((fragment, fragIndex) => {
          if (fragment.type === 'link') {
            return (
              <a
                key={fragIndex}
                href={fragment.value}
                target="_blank"
                rel="noopener noreferrer"
                style={{ color: '#e3f2fd', textDecoration: 'underline' }}
              >
                {fragment.value}
              </a>
            )
          }
          return <span key={fragIndex}>{fragment.value}</span>
        })}
      </p>
    </Paper>
  );
})}

注意事项

  • 给链接标签添加rel="noopener noreferrer"是必要的安全配置,避免新打开的页面对当前页面造成安全风险
  • 给p标签增加word-break: break-all样式,避免长URL撑破消息气泡
  • 原代码中写了遍历逻辑的useEffect可以直接删除,不需要提前处理聊天数据
  • 正则每次执行匹配前重置lastIndex,避免连续渲染多条消息时出现匹配位置错位的问题

内容的提问来源于stack exchange,提问作者user12102361

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 08:33:11