如何阻止函数组件不必要调用?依赖项排查与重渲染触发原因定位
导致该模型层组件重复触发数据拉取的常见原因如下
- 组件自身被重复挂载/渲染
- 父组件重渲染时,若传递给
ForeignListContFct的props引用发生变化(比如父组件每次渲染都生成新的props对象),会触发该组件重渲染,每次重渲染都会执行CustomFetch逻辑触发请求 DataContext的value发生变更:只要DataContext.Provider传递的value对象引用更新,不管用到的word、setLang1Library有没有变化,都会触发该组件重渲染;如果word的值发生了修改,还会直接改变请求URL,触发新的拉取
- 父组件重渲染时,若传递给
- 渲染逻辑中的副作用没有做触发限制
当前你将CustomFetch直接放在组件顶层执行,没有用useEffect包裹做依赖项控制,只要组件重渲染就会执行一次拉取逻辑。正常的异步请求逻辑应该用useEffect包裹,指定依赖项(比如仅当word变化时才触发请求)。 - 状态更新导致的循环渲染
你在组件同步渲染逻辑中直接调用setLang1Library(data)更新上下文状态,这个操作会触发DataContext更新,进而导致该组件自身重渲染,重渲染后如果data仍满足非空条件,又会再次调用setLang1Library,形成无限循环,每次循环都会触发新的拉取请求。 CustomFetch钩子的实现问题
如果CustomFetch内部没有做缓存、或者依赖项判断逻辑错误,哪怕传入的URL没有变化,也可能重复触发请求。比如CustomFetch内部没有用useEffect包裹请求逻辑,或者依赖项数组配置错误,都会导致每次调用钩子就发起请求。
临时修复方案
你可以先把状态更新逻辑用useEffect包裹,限制触发时机,避免循环渲染:
function ForeignListContFct(props) { let libraryName = props.props.language; const { word, setLang1Library } = useContext(DataContext); var URL = 'https://localhost:44307/api/langs/' + word; console.log('Fetching :' + URL); const { loading, error, data } = CustomFetch(URL, word, null, false); // 仅当data或setLang1Library变化时才更新上下文状态 useEffect(() => { if (data !== null && data.length > 0) { setLang1Library(data); } }, [data, setLang1Library]) if (loading) { return <div>Loading ...</div>; } if (word === '') { return <div>Word not searched yet ! ..</div>; } if (error) { return ( <div> <h3>Error: {error.message}</h3> <h3>{error.stack}</h3> </div> ); } return <ForeignList props={{ language: libraryName }}></ForeignList>; }
如果修改后还是存在重复请求,进一步检查CustomFetch的内部实现,确认请求是否做了重复调用拦截。
内容的提问来源于stack exchange,提问作者GeoSystems
相关产品推荐
相关产品推荐

