预订应用中React useEffect依赖缺失问题求助:避免无限循环
问题
开发预订应用时,点击预订详情按钮可成功获取数据,但React的useEffect钩子出现警告:
React Hook React.useEffect has a missing dependency: 'getDetails'. Either include it or remove the dependency array.
不能移除依赖数组(否则会引发无限循环),尝试添加相关变量后仍有黄色下划线提示,代码如下:
const BookedDetails = () => { const { user } = useSelector((state) => state.userAuth) const userID = user?.user?._id const [details, setDetails] = React.useState([]) const [loading, setLoading] = React.useState(false) const [invoiceLoad, setInvoiceLoad] = React.useState(false) const [currentPage, setCurrentPage] = React.useState(1) const [postPerPage, setPostPerPage] = React.useState(4) const indexOfLastPost = currentPage * postPerPage const indexOfFirstPost = indexOfLastPost - postPerPage const currenPosts = details.slice(indexOfFirstPost, indexOfLastPost) const pages = [] for(let i = 1; i <= Math.ceil(details.length / postPerPage); i++) { pages.push(i) } const paginate = (x) => { setCurrentPage(x) } const getDetails = async () => { const config = { headers: { "Content-Type": "application/json", } } try { setLoading(true) const res = await axios.post('/api/bookingDetails/bookDetails', { userID }, config ) //console.log(res.data.user) setDetails(res.data.user) setLoading(false) } catch (error) { console.log(error.message) setLoading(false) } } React.useEffect(() => { getDetails() },[ ]) // << dependency is yellow underlined. }
解决方案
1. 用useCallback缓存getDetails函数
getDetails会在每次组件渲染时重新创建,直接加入依赖数组会触发useEffect重复执行。使用useCallback缓存函数,只有当依赖的userID变化时才重新生成函数,这样就能安全将getDetails加入effect的依赖数组,同时避免无限循环:
import { useCallback } from 'react'; // ... 其他代码保持不变 const getDetails = useCallback(async () => { const config = { headers: { "Content-Type": "application/json", } } try { setLoading(true) const res = await axios.post('/api/bookingDetails/bookDetails', { userID }, config ) setDetails(res.data.user) setLoading(false) } catch (error) { console.log(error.message) setLoading(false) } }, [userID]) // 仅当userID变化时,重新创建getDetails React.useEffect(() => { getDetails() }, [getDetails]) // 加入getDetails作为依赖
2. 将getDetails移入useEffect内部
如果getDetails仅在这个useEffect中调用,直接把函数写进effect内部,这样就不需要额外处理依赖:
React.useEffect(() => { const getDetails = async () => { const config = { headers: { "Content-Type": "application/json", } } try { setLoading(true) const res = await axios.post('/api/bookingDetails/bookDetails', { userID }, config ) setDetails(res.data.user) setLoading(false) } catch (error) { console.log(error.message) setLoading(false) } } getDetails() }, [userID]) // 仅需加入userID作为依赖
3. 用ESLint注释忽略警告(不推荐)
如果确认无需依赖更新触发effect,可以添加注释让ESLint忽略警告,但这是临时方案,可能隐藏潜在的依赖问题:
React.useEffect(() => { getDetails() }, []) // eslint-disable-line react-hooks/exhaustive-deps
内容的提问来源于stack exchange,提问作者Peret
相关产品推荐
相关产品推荐

