Next.js中如何避免服务端已有数据时客户端useEffect执行
解决Next.js SSR页面初始加载时避免执行Hook内useEffect的问题
核心思路是用useRef标记首次渲染,让useEffect只在筛选选项(selectedOptions)主动变化时执行,跳过页面初始加载的触发。
修改自定义Hook代码(useFilterOptions.js)
- 引入
useRef:
import { useEffect, useRef } from 'react';
- 在Hook内部添加首次渲染标记并调整useEffect逻辑:
// 标记是否为组件首次渲染 const isFirstRender = useRef(true); useEffect(() => { // 首次渲染直接跳过,不执行API请求 if (isFirstRender.current) { isFirstRender.current = false; return; } // 以下是原有的API请求逻辑 const queryParams = getUrlParams(); const formQuery = queryParams !== '' ? `&${getUrlParams()}` : ''; const formSearchQuery = queryParams !== '' ? `${getUrlParams()}` : ''; const variables = { countryCode, languageCode, page: pageNumber, // Page number starts from 0 count: PRODUCT_COUNT, queryParam: isSearch ? formSearchQuery : formQuery, gender: genderParam, }; if (!isSearch) { variables.urlPath = urlPath; } fetchProductListData({ variables }); }, [selectedOptions, getUrlParams, countryCode, languageCode, pageNumber, PRODUCT_COUNT, isSearch, genderParam, urlPath, fetchProductListData]);
为什么这样有效?
useRef的.current属性在组件整个生命周期内保持引用不变,不会触发组件重渲染。- 组件首次挂载时,
isFirstRender.current为true,进入useEffect后直接将其置为false并返回,跳过API请求。 - 后续只有当
selectedOptions(或其他依赖项)主动变化时,useEffect才会再次触发,此时isFirstRender.current为false,会执行API请求逻辑。
补充说明
- 确保useEffect的依赖项完整:把所有在useEffect内部用到的外部变量/函数都加入依赖数组,避免闭包导致的旧值问题,ESLint通常会提示缺失的依赖。
- 如果需要兼容
selectedOptions初始值非空的场景,这种方式依然有效——不管初始值是什么,首次渲染都会跳过,只有用户主动修改复选框导致selectedOptions变化时才会触发请求。
内容的提问来源于stack exchange,提问作者H.Husain
相关产品推荐
相关产品推荐

