React调用clickAction函数时滑块切换出现屏幕闪烁问题求助
React滑块组件切换时屏幕闪烁问题
我正在开发一个React滑块组件,点击项目切换到第二个项目时,调用clickAction()函数会出现屏幕闪烁,问题刚好在调用这个函数时发生。
相关代码
VerticalCarousel组件(点击事件处理部分)
const VerticalCarousel = ({ clickActionTransfer }) => { . .. ... <button data-glitch={item.type} type="button" onClick={clickActionTransfer} key={i}> CLICK {item.type} </button> };
Slider组件代码
import React, { useState, useEffect } from "react"; import VerticalCarousel from "./carousel/VerticalCarousel"; const Slider = ({ getData, idd, clickAction, children }) => { const [displayTitleState, setDisplayTitleState] = useState(true); const [displayCarouselState, setDisplayCarouselState] = useState(true); const [currentIndex, setCurrentIndex] = useState(0); const [length, setLength] = useState(children.length); const handleSlideClick = () => { if (currentIndex < length - 1) { setCurrentIndex((prevState) => prevState + 1); } setDisplayCarouselState(false); setTimeout(() => { setDisplayTitleState(false); clickAction(); }, 1000); setTimeout(() => { setDisplayTitleState(true); setDisplayCarouselState(true); }, 2600); }; useEffect(() => { setLength(children.length); }, [children]); return ( <div className="slider__container"> {getData.map((i) => { return ( idd === i.id && ( <div key={i.id}> <div style={{ transform: `translateX(-${currentIndex * 100}%)`, display: "flex", transition: "all .5s linear", }} > {children} </div> <div className="slider__content"> <div className={ "slider__left " + (i.theme === "light" ? "light-theme" : "") } > <div className="slider__progressBar"> {i.progressBar.nb1} <span className="slider__progressBar-lightTxt"> {i.progressBar.nb1} </span> {i.progressBar.text} </div> <h1 className={displayTitleState ? "showTitle" : "hideTitle"}> {i.title} </h1> </div> <div className={`slider__right ${ displayCarouselState ? "showCarousel" : "hideCarousel" } ${i.theme === "light" ? "light-theme" : ""}`} > <VerticalCarousel data={i.slider} clickActionTransfer={handleSlideClick} /> </div> </div> </div> ) ); })} </div> ); }; export default Slider;
App.js代码
import React, { useState, useEffect } from "react"; import Slider from "./Slider"; import "./App.scss"; function App() { const [loadSlide, setLoadSlide] = useState(0); const [data, setData] = useState([]); const handleclick = () => { setLoadSlide(loadSlide + 1); }; useEffect(() => { setLoadSlide((loadSlide) => loadSlide + 1); fetch("/data.json") .then((response) => response.json()) .then((json) => { setData(json.lvmh.sliders); }); }, []); return ( <div className="App"> <div className={ "slider " + (loadSlide >= 1 && loadSlide <= data.length && loadSlide + 1 && `ifSlider`) } > <> {loadSlide >= 0 && loadSlide <= data.length && loadSlide + 1 && ( <Slider clickAction={handleclick} idd={loadSlide} getData={data}> {data.map((img) => { return ( <img className="slider__bg---- " src={img.img} alt="" /> ); })} </Slider> )} </> </div> </div> ); } export default App;
问题分析与解决方案
核心问题
- 闭包导致状态更新异常:
handleclick中直接使用loadSlide + 1会捕获初始状态值,导致状态更新逻辑出错,引发组件不必要的重复渲染。 - 组件频繁卸载重建:App中的条件渲染逻辑会在
loadSlide变化时卸载并重新挂载Slider组件,打断内部动画状态,直接导致屏幕闪烁。
修复步骤
修复状态更新的闭包问题
改用函数式更新获取最新状态值,避免闭包陷阱:const handleclick = () => { setLoadSlide(prev => prev + 1); };避免Slider组件卸载重建
简化条件渲染逻辑,只要数据加载完成就保留Slider实例,通过idd控制显示内容,同时给列表项添加唯一key:return ( <div className="App"> <div className={`slider ${loadSlide >= 1 && loadSlide <= data.length ? 'ifSlider' : ''}`} > {data.length > 0 && ( <Slider clickAction={handleclick} idd={loadSlide} getData={data}> {data.map((img) => ( <img key={img.id} className="slider__bg---- " src={img.img} alt="" /> ))} </Slider> )} </div> </div> );优化Slider组件的状态逻辑
移除冗余的dataSlider状态,直接使用传入的getDataprop,减少不必要的状态同步操作(已在上方修改后的Slider代码中体现)。
以上修改可解决状态更新异常和组件频繁重建的问题,彻底消除屏幕闪烁现象。
内容的提问来源于stack exchange,提问作者Madara uchi
相关产品推荐
相关产品推荐

