当前位置: 首页 > article >正文

React写关键字高亮的三个方案

1.js正则replaceAll+dangerouslySetInnerHTML={{ __html: xxx }}危险属性

步骤最简单,但是是危险属性,不推荐使用,项目中实在没有头绪,可以使用它应急

通过useMemo计算得到新的状态值,赋值给dangerouslySetInnerHTML属性的__html

关键代码:

const [state1, setState1] = useState('我爱中国,中国爱我')

const updateState1 = useMemo(() => {
    return state1.replaceAll('中国', '<span style="color:red;">中国</span>')
  }, [state1])


<div dangerouslySetInnerHTML={{ __html: updateState1 }}></div>

2.useMemo计算遍历后将关键字替换为React标签写法(内容为关键字),使用_.map渲染

(要不是replace不能转换为React标签,只支持字符串也不用这么麻烦)

关键代码:

const updateState2 = useMemo(() => {
    return highlightPassword(state2, '_.map_')
  }, [state2])


  function highlightPassword(str0: any, key_prefix?: string) {
    const password = '中国';
    const pattern = new RegExp(`\\B(?=((${password})+)+(?!(${password})))`, 'g')
    return str0.replace(pattern, '||||').split('||||').map((item, index) => {
      const idx = item.indexOf(password)
      return <span key={key_prefix + index}>
        {
          idx >= 0
            ? <><span style={{ color: 'red' }}>{item.substring(0, password.length)}</span>{item.substring(password.length, item.length)}</>
            : item
        }
      </span>
    });
  }


      <p>map遍历children元素:</p>
      {_.map(updateState2, (child) => {
        return child
      })}

3.遍历后将关键字替换为React标签写法(内容为关键字),使用ReactDOM.render方法插入到指定元素中

关键代码:

const Test = () => {
  const [state2, setState2] = useState<any>('我爱中国,中国中国爱我')
  useEffect(() => {
    // 遍历将关键字换成react写法的标签,使用ReactDOM.render方法渲染到页面上
    const str = highlightPassword(state2, 'ReactDOM.render_')
    ReactDOM.render(<div>{str}</div>, document.getElementsByClassName('my-highlight-test')[0])
  }, [state2])


 function highlightPassword(str0: any, key_prefix?: string) {
    const password = '中国';
    const pattern = new RegExp(`\\B(?=((${password})+)+(?!(${password})))`, 'g')
    return str0.replace(pattern, '||||').split('||||').map((item, index) => {
      const idx = item.indexOf(password)
      return <span key={key_prefix + index}>
        {
          idx >= 0
            ? <><span style={{ color: 'red' }}>{item.substring(0, password.length)}</span>{item.substring(password.length, item.length)}</>
            : item
        }
      </span>
    });
  }


      <p>ReactDOM.render方法:</p>
      <div className="my-highlight-test"></div>


完整代码示例: 

import React, { useEffect, useMemo, useState } from 'react'
import ReactDOM from 'react-dom';
import _ from 'lodash';

const Test = () => {
  const [password,] = useState('中国')
  const [state1, setState1] = useState('我爱中国,中国爱我')
  const [state2, setState2] = useState<any>('我爱中国,中国中国爱我')
  useEffect(() => {
    // 遍历将关键字换成react写法的标签,使用ReactDOM.render方法渲染到页面上
    const str = highlightPassword(state2, 'ReactDOM.render_')
    ReactDOM.render(<div>{str}</div>, document.getElementsByClassName('my-highlight-test')[0])
  }, [state2])

  const updateState1 = useMemo(() => {
    return state1.replaceAll(password, str => `<span style="color:red;">${str}</span>`)
  }, [state1])

  const updateState2 = useMemo(() => {
    return highlightPassword(state2, '_.map_')
  }, [state2])

  useEffect(() => {
    setTimeout(() => {
      setState1('哈哈哈,中国万岁,万岁万万岁,中国加油!')
      setState2('哈哈哈,中国中国万岁,万岁万万岁,中国中国加油!爱你中国!')
    }, 2000)
  }, [])


  function highlightPassword(str0: any, key_prefix?: string) {
    const pattern = new RegExp(`\\B(?=((${password})+)+(?!(${password})))`, 'g')
    return str0.replace(pattern, '||||').split('||||').map((item, index) => {
      const idx = item.indexOf(password)
      return <span key={key_prefix + index}>
        {
          idx >= 0
            ? <><span style={{ color: 'red' }}>{item.substring(0, password.length)}</span>{item.substring(password.length, item.length)}</>
            : item
        }
      </span>
    });
  }

  return (
    <div>
      <p>dangerouslySetInnerHTML方式:</p>
      <div dangerouslySetInnerHTML={{ __html: updateState1 }}></div>
      <p>map遍历children元素:</p>
      {_.map(updateState2, (child) => {
        return child
      })}
      <p>ReactDOM.render方法:</p>
      <div className="my-highlight-test"></div>
    </div>
  )
}

export default Test

显示效果:

初始化页面时:

2cacd40d3968477585d8674b3ff964db.png

2s后(模拟异步请求数据)显示:

73bd463cfc634e0f894bd4114ae05331.png

代码仓库地址:

命运推手/my_web


http://www.kler.cn/a/371052.html

相关文章:

  • 大语言模型数据流程源码解读(基于llama3模型)
  • 基于SpringBoot云养鸡互动平台的设计与实现
  • 力扣每日一题 685. 冗余连接 II
  • 【JavaEE】【多线程】定时器
  • 用xshell给服务器上传jar包
  • vue3中mitt和pinia的区别和主要用途,是否有可重合的部分?
  • Node.js:内置模块
  • Docker | 通过commit操作实例来认识镜像底层实现的原理以及学会打包镜像
  • 前端零基础入门到上班:【Day3】从零开始构建网页骨架HTML
  • 【AIGC】2024-arXiv-Lumiere:视频生成的时空扩散模型
  • static函数和友元
  • Linux云计算 |【第五阶段】ARCHITECTURE-DAY5
  • 【华为HCIP实战课程十八】OSPF的外部路由类型,网络工程师
  • df -h 和df -i 的区别
  • pip命令行安装pytest 一直报错
  • springboot075电影评论网站系统设计与实现(论文+源码)_kaic
  • Bash、sh 和 Shell都弄混了?
  • 软考架构师论文范文(游戏后端)
  • 为 Python 项目配置 Git 忽略文件的实用指南
  • SSA-CNN-LSTM-MATT多头注意力机制多特征分类预测
  • vue2项目在发布后更新,提示用户刷新页面
  • MySQL史上最全总结
  • Go语言中数据类型与变量的用法
  • 算法训练(leetcode)二刷第十天 | 150. 逆波兰表达式求值、*239. 滑动窗口最大值、*347. 前 K 个高频元素
  • 明日周刊-第25期
  • Hash表算法