使用TagCloud-reactJS构建移动端标签云出现重复问题求助
标签云重复显示问题排查与解决
我在个人作品集网站适配移动端标签云时,使用TagCloud-reactJS库,遇到标签云持续重复显示的问题,移动端效果如图:
相关代码
index.js
import React, { useEffect, useState } from 'react' import TagCloud from 'TagCloud'; import AnimatedLetters from '../AnimatedLetters'; import './index.scss' import Loader from 'react-loaders'; import TagsCanvas from 'react-tags-canvas' const container = '.tagCloud'; const texts = [ 'React.js', 'Python', 'JavaScript', 'CSS3', 'Java', 'Jquery', 'HTML5', 'C#', 'Ajax', 'ASP.NET', 'SQL Server 2019', 'Visual Studio 2019', 'Team Foundation Server (GIT)', 'Google Maps API', 'SendGrid', 'Telerik UI', 'Blazor', 'Android Studio' ]; const options = { radius: 400, maxSpeed: 'fast', initSpeed: 'fast', direction: 135, keep: true }; const Skills = () => { useEffect(() => { TagCloud(container, texts, options); }) useEffect(() => { setTimeout(() => { return TagCloud(container, texts, options) }, 4000) }, []) const [letterClass, setLetterClass] = useState('text-animate') useEffect(() => { setTimeout(() => { return setLetterClass('text-animate-hover') }, 3000) }, []) return ( <div className='container skills-page'> <div className="text-zone"> <h1> <AnimatedLetters letterClass={letterClass} strArray={['S', 'k', 'i', 'l', 'l', 's']} idx={15} /> </h1> <p> Expert in a wide variety of coding languages such as HTML5, CSS3, Javascript, Jquery, React, Bootstrap, Git, Java, Python, C#, SQL, etc. </p> <p float="left"> I specialize in building aesthetic looking websites on the front end, as well as making my back end code extremely efficient with the least amount of overhead possible. I try my best to ensure each page I build has a mobile friendly design and that my code is as easy to understand and as reusable as it can possibly be. </p> <p> Feel free to visit my <a href='https://github.com/EricTilton'>Github</a> page for some of my work. </p> </div> <div className='cloudContainer'> <span id="root" className="tagCloud"/> </div> <div className='black'> </div> <Loader type="ball-grid-pulse" /> </div> ) } export default Skills
index.scss
.container.skills-page { a { color: #00e1ff } body{ margin-top: 3px; padding: 1px; box-sizing: border-box; } .text-zone{ margin-bottom: 400px; } .tagcloud { position: absolute; top: 100px; right: auto; bottom: 6000px; color: #fff; font-family: 'Poppins', sans-serif; font-size: 15px; font-weight: 650; margin-left: 50%; mask-repeat: no-repeat; } .tagcloud--item:hover { color: #00e1ff } } @media screen and (max-width: 1200px) { .cloudContainer{ position: relative; transform: scale(0.5) translate(-100%, -100%); top: 800px; right: 25px; } .tagCloud { position: relative; top: auto; bottom: 500px; color: #fff; font-family: 'Poppins', sans-serif; font-size: 15px; font-weight: 650; margin-right: 200%; mask-repeat: no-repeat; width: 100%; height: 100%; transform: scale(0.5) translate(-100%, -100%); } h1 { font-size: 53px; font-family: 'Coolvetica'; color: #00e1ff; font-weight: 400; margin-top: 0; position: relative; margin-bottom: 40px; left: -10px; &:before { content: '<h1>'; font-family: 'La Belle Aurore', cursive; color: #00e1ff; font-size: 18px; position: absolute; margin-top: -10px; left: -10px; opacity: 0.6; line-height: 18px; } &:after { content: '<h1/>'; font-family: 'La Belle Aurore', cursive; color: #00e1ff; font-size: 18px; line-height: 18px; position: absolute; left: -30px; bottom: -20px; margin-left: 20px; opacity: 0.6; } } }
问题根源与修复方案
问题根源
- 重复初始化TagCloud:第一个
useEffect无依赖数组,组件每次渲染都会执行初始化;加上第二个4秒延迟的初始化,导致多次生成标签,造成重复显示。 - 容器选择器不唯一:使用类选择器
.tagCloud,若页面存在多个匹配元素或组件重复渲染,会重复挂载标签。
修复步骤
- 合并初始化逻辑,确保仅执行一次
删除原有两个重复的useEffect,替换为以下代码,确保组件挂载时仅初始化一次,且卸载时清理实例:
useEffect(() => { // 清除容器内已有内容,避免重复 const cloudContainer = document.querySelector(container); if (cloudContainer) { cloudContainer.innerHTML = ''; } // 初始化标签云 const cloudInstance = TagCloud(container, texts, options); // 组件卸载时销毁实例 return () => { cloudInstance.destroy?.(); }; }, []);
- 确保容器唯一性
修改容器的id为唯一值,同时更新选择器:
// 修改container选择器 const container = '#tag-cloud-container'; // 对应JSX部分 <span id="tag-cloud-container" className="tagCloud"/>
- 简化移动端样式
当前移动端样式的transform和定位易导致视觉重复,调整为:
@media screen and (max-width: 1200px) { .cloudContainer{ position: relative; transform: scale(0.7); top: 200px; margin: 0 auto; width: 80%; } .tagCloud { position: relative; color: #fff; font-family: 'Poppins', sans-serif; font-size: 12px; font-weight: 650; width: 100%; height: 400px; transform: none; } }
额外建议
- 检查
Skills组件是否被多次渲染(如路由切换重复挂载),确保组件仅渲染一次。 - 查阅TagCloud库文档,确认是否有官方React组件用法,减少直接操作DOM带来的兼容性问题。
内容的提问来源于stack exchange,提问作者Eric Tilton
相关产品推荐
相关产品推荐

