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

React JS实现文本指定词加粗高亮 点击按钮无响应问题

问题根因

你的代码没有生效是三个核心错误导致的:

  • 违背React状态驱动的核心逻辑:你全程通过document.getElementById直接操作DOM,既没有把处理后的内容存到组件状态中,也没有把处理结果嵌入JSX参与渲染,页面自然不会有任何变化。
  • 对react-string-replace的用法完全错误:这个库是纯函数,执行后不会修改传入的原始参数,只会返回处理完成的React节点数组;你两次调用都没有接收返回值,且第二版代码直接传入DOM元素对象作为第一个参数(该库要求第一个参数必须是纯字符串或者React节点数组),库根本无法正常执行匹配逻辑。
  • 渲染容器错误:你试图把带<span>标签的富文本内容放到<textarea>里渲染,textarea是原生表单控件,内部只能展示纯文本,完全不支持嵌套HTML标签,就算你把内容塞进去也不可能显示加粗效果。
修复方案

直接用React状态管理所有可变数据,移除所有手动DOM操作,区分纯文本编辑区和富文本预览区,处理后的高亮内容直接在JSX中渲染即可。
完整可运行代码如下:

import React, { useState } from 'react'
import "./Blog.css"
import reactStringReplace from 'react-string-replace';

// 正则特殊字符转义工具
const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");

export default function Blog() {
    const [titleText, setTitText] = useState("Enter Title here....");
    const [desText, setDesText] = useState("Enter Text here....");
    // 存储触发高亮的关键词
    const [searchKeyword, setSearchKeyword] = useState("");
    // 存储搜索框实时输入值
    const [searchInput, setSearchInput] = useState("");

    // 点击按钮触发高亮
    const handleSearch = () => {
        setSearchKeyword(searchInput.trim());
    }

    const handleOnChangetit = (event) => {
        setTitText(event.target.value);
    }
    const handleOnChangedes = (event) => {
        setDesText(event.target.value);
    }
    const handleSearchInputChange = (e) => {
        setSearchInput(e.target.value);
    }

    // 生成高亮后的正文内容
    const renderHighlightedText = () => {
        if (!searchKeyword) return desText;
        const pattern = new RegExp(escapeRegExp(searchKeyword), "gi");
        return reactStringReplace(desText, pattern, (match, i) => (
            <span key={i} style={{ fontWeight: 'bold' }}>{match}</span>
        ))
    }

    // 生成高亮后的标题内容
    const renderHighlightedTitle = () => {
        if (!searchKeyword) return titleText;
        const pattern = new RegExp(escapeRegExp(searchKeyword), "gi");
        return reactStringReplace(titleText, pattern, (match, i) => (
            <span key={i} style={{ fontWeight: 'bold' }}>{match}</span>
        ))
    }

    return (
        <>
            <div className="blogButtons">
                <input 
                    className="searchbar" 
                    type="search" 
                    value={searchInput}
                    onChange={handleSearchInputChange}
                    placeholder="Search" 
                    aria-label="Search..." 
                />
                <button className="btn btn-outline-success" onClick={handleSearch} type="button">
                    <i className="fa-solid fa-magnifying-glass"> Bold Text</i>
                </button>
            </div>
            <div className="textbox">
                {/* 纯文本编辑区 */}
                <textarea type="text" value={titleText} onChange={handleOnChangetit} className='blogtitle' />
                <textarea type="text" value={desText} onChange={handleOnChangedes} className='blogarea' />
                {/* 高亮预览区 */}
                <div className="blog-preview-title">{renderHighlightedTitle()}</div>
                <div className="blog-preview-content" id="blog-text">{renderHighlightedText()}</div>
            </div>
        </>
    )
}
关键修改说明
  • 所有可变内容全部通过React state管理,数据修改统一走setState触发视图更新,完全移除手动DOM操作逻辑,从根源上避免“处理了内容但页面不刷新”的问题。
  • 修正react-string-replace调用方式:传入纯文本作为匹配源,接收函数返回的React节点数组直接参与渲染。
  • 区分编辑区和预览区:textarea仅负责纯文本输入,普通div负责渲染带加粗样式的富文本内容,解决容器不支持HTML标签的问题。如果不需要单独编辑区,直接删除两个textarea标签即可。
  • 按钮type改为button,避免默认submit行为触发非预期的页面刷新。
  • 搜索框改为受控组件,输入内容实时同步到state,不用点击时再去DOM节点中取值,逻辑更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 06:15:44