Next.js中Session Storage存储滑块偏好值返回首页被重置的问题求助
问题分析
问题出在组件初始化阶段:
- 你给
useState设置的初始值是null,导致组件挂载时,依赖value的useEffect会立即把sessionStorage中的值覆盖为null。 - 随后执行的空依赖
useEffect读取的已经是被覆盖后的null,最终把state设为null,形成恶性循环。
另外你的Slider组件里有个冗余的handleChange函数,既没有用到,还会因为内部没有setValue导致报错,需要删掉。
修复方案
1. 初始化state时直接读取sessionStorage
不需要用额外的useEffect初始化state,直接在useState的初始化函数中读取sessionStorage,这样初始值就会是用户之前存储的偏好值,避免挂载时写入null。
2. 移除冗余代码
删掉Slider组件内多余的handleChange函数,同时移除ImageGallery中用于初始化state的空依赖useEffect。
修改后的代码
Slider组件
export default function Slider({ value, handleChange }: ISlider) { return ( <input className={styles.slider} min={1} max={3} step={1} type="range" value={value} onInput={handleChange} onChange={handleChange} /> ); }
ImageGallery组件
export default function ImageGallery({ projects, }: { projects: any; }): JSX.Element { // 初始化时直接从sessionStorage取值,默认值设为1 const [value, setValue] = useState(() => { if (typeof window !== "undefined") { const storedValue = window.sessionStorage.getItem("value"); return storedValue ? JSON.parse(storedValue) : 1; } return 1; }); const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => { setValue(Number(event.target.value)); // 转为number类型,避免字符串问题 }; // 仅在value变化时存储到sessionStorage useEffect(() => { if (typeof window !== "undefined") { window.sessionStorage.setItem("value", JSON.stringify(value)); } }, [value]); const breakpointColumnsObj = { default: 4, 1100: 3, 700: 2, 500: value }; return ( <> <Masonry breakpointCols={breakpointColumnsObj} className={styles.myMasonryGrid} columnClassName={styles.myMasonryGridColumn} > {projects.map((item: any) => { const images = item.images.data.attributes.formats.large; return ( <ImageCard key={item.slug} src={images.url} alt={item.images.data.attributes.caption} width={images.width} height={images.height} slug={item.slug} id={item.slug} /> ); })} </Masonry> <Slider value={value} handleChange={handleChange} /> </> ); }
额外优化建议
- 给
ISlider接口添加明确的类型定义:interface ISlider { value: number; handleChange: (event: React.ChangeEvent<HTMLInputElement>) => void; } - 给
projects参数定义具体的类型,避免使用any,提升代码可维护性。
内容的提问来源于stack exchange,提问作者Antoni
相关产品推荐
相关产品推荐

