如何在 React 中基于字数限制动态截断并展开段落内容

1次阅读

如何在 React 中基于字数限制动态截断并展开段落内容

本文介绍如何构建一个可复用的 react “显示更多”组件,通过 wordCount 属性精确控制初始显示的单词数量,并支持点击按钮切换完整/截断视图,避免字符级截断导致的语义断裂。

本文介绍如何构建一个可复用的 react “显示更多”组件,通过 `wordcount` 属性精确控制初始显示的单词数量,并支持点击按钮切换完整/截断视图,避免字符级截断导致的语义断裂。

在 React 应用中,仅按字符长度(如 substring)截断文本容易破坏单词完整性,造成阅读障碍(例如将 “consectetur” 截成 “consec”)。更合理的方式是按单词粒度进行分割与拼接。核心思路是:将原文本以空格为分隔符拆分为单词数组,再根据 wordCount 取前 N 个单词,最后安全拼接回字符串

以下是推荐实现的 ShowMore 组件:

import React, { useState } from 'react';  const ShowMore = ({ text, wordCount }) => {   const [expanded, setExpanded] = useState(false);    const toggleExpand = () => setExpanded(prev => !prev);    // 安全分割:使用正则 /s+/ 处理多个空格、换行、制表符   const words = text.trim().split(/s+/).Filter(word => word.Length > 0);    const displayedWords = expanded      ? words      : words.slice(0, wordCount);    return (     <div className="show-more">       <p>         {displayedWords.map((word, index) => (           <span key={index}>{word}{index < displayedWords.length - 1 ? ' ' : ''}</span>         ))}         {!expanded && words.length > wordCount && <span>…</span>}       </p>       {words.length > wordCount && (         <button            onClick={toggleExpand}           aria-expanded={expanded}           aria-label={expanded ? '收起内容' : '展开查看更多'}         >           {expanded ? '收起' : '展开'}         </button>       )}     </div>   ); };  export default ShowMore;

关键优化点说明

  • 使用 text.trim().split(/s+/).filter(…) 替代简单 split(‘ ‘),可正确处理连续空格、换行符及首尾空白;
  • 渲染时手动控制单词间空格,避免末尾冗余空格;
  • 添加省略号 … 和 aria-* 属性,提升可访问性与用户体验;
  • 仅在实际需要时渲染按钮(即 words.length > wordCount),避免无意义控件;

? 使用示例

import ShowMore from './ShowMore';  function App() {   const longText = "React is a JavaScript library for building user interfaces. It lets you compose complex UIs from small and isolated pieces of code called components.";    return (     <div className="app">       <ShowMore text={longText} wordCount={8} />     </div>   ); }  export default App;

⚠️ 注意事项

  • 该方案默认以空格为单词边界,不适用于中日韩等无空格分隔的语言;若需支持多语言,建议集成 Intl.Segmenter 或专用分词库;
  • 对含 HTML 标签或富文本的场景,需先剥离标签或使用 dangerouslySetInnerHTML(需确保内容可信);
  • 如需动画过渡效果,可结合 CSS max-height + transition 或 framer-motion 实现平滑展开。

通过此组件,你可在任意页面中灵活控制文本展示粒度,兼顾语义准确性与交互友好性。

text=ZqhQzanResources