keen-slider与Fetch数据配合异常问题求助
解决方案
一、修复首次加载滑块冻结问题
问题根源:滑块初始化时数据尚未加载,无幻灯片内容;数据加载完成后,滑块未自动重新计算布局,仅窗口 resize 时才触发重计算。
修改方案:
- 监听数据变化,当数据加载完成后调用滑块实例的
update方法,强制重新计算布局:
// 新增 useEffect 监听 data 变化 useEffect(() => { if (instanceRef.current && data.length > 0) { instanceRef.current.update(); } }, [data]);
- 调整滑块配置初始化时机:将基础配置直接作为
useKeenSlider的初始参数,避免空配置初始化滑块:
// 直接传入完整配置,不再用空对象初始化 const [sliderRef, instanceRef] = useKeenSlider({ initial: 0, slides: { origin: "center", perView: 3, spacing: 25 }, slideChanged(slider) { setCurrentSlide(slider.track.details.rel); }, created() { setLoaded(true); } });
- 简化原有
useEffect,仅处理数据请求:
useEffect(() => { fetch("./data.json") .then((response) => response.json()) .then((json) => { setData(json); }); }, []);
二、修复左右箭头无法显示问题
问题根源:通常是缺少必要样式、未绑定滑块导航方法,或未引入滑块默认样式。
修改方案:
- 引入keen-slider默认样式:
import "keen-slider/keen-slider.css";
- 给箭头添加基础定位样式(可根据需求调整):
.keen-slider__arrow { position: absolute; top: 50%; transform: translateY(-50%); border: none; background: rgba(0,0,0,0.5); color: #fff; font-size: 20px; padding: 0 12px; cursor: pointer; z-index: 10; } .keen-slider__arrow--left { left: 15px; } .keen-slider__arrow--right { right: 15px; }
- 正确绑定箭头点击事件到滑块实例:
{loaded && ( <> <button className="keen-slider__arrow keen-slider__arrow--left" onClick={() => instanceRef.current?.prev()} > ← </button> <button className="keen-slider__arrow keen-slider__arrow--right" onClick={() => instanceRef.current?.next()} > → </button> </> )}
核心修改后代码示例
import { useState, useEffect } from "react"; import { useKeenSlider } from "keen-slider/react"; import "keen-slider/keen-slider.css"; export default function App() { const [data, setData] = useState([]); const [currentSlide, setCurrentSlide] = useState(0); const [loaded, setLoaded] = useState(false); const [sliderRef, instanceRef] = useKeenSlider({ initial: 0, slides: { origin: "center", perView: 3, spacing: 25 }, slideChanged(slider) { setCurrentSlide(slider.track.details.rel); }, created() { setLoaded(true); } }); useEffect(() => { fetch("./data.json") .then((response) => response.json()) .then((json) => { setData(json); }); }, []); useEffect(() => { if (instanceRef.current && data.length > 0) { instanceRef.current.update(); } }, [data]); return ( <div className="App"> <div className="keen-slider" ref={sliderRef}> {data.map((item) => ( <div className="keen-slider__slide" key={item.id}> <h2>{item.title}</h2> <p>{item.content}</p> </div> ))} </div> {loaded && ( <> <button className="keen-slider__arrow keen-slider__arrow--left" onClick={() => instanceRef.current?.prev()} > ← </button> <button className="keen-slider__arrow keen-slider__arrow--right" onClick={() => instanceRef.current?.next()} > → </button> </> )} </div> ); }
内容的提问来源于stack exchange,提问作者Salmonella mayonnaise
相关产品推荐
相关产品推荐

