rus*_*uss 58 reactjs eslint create-react-app react-hooks
使用React 16.8.6(在以前的版本16.8.3中很好),当我尝试防止在获取请求上发生无限循环时,出现此错误
./src/components/BusinessesList.js
Line 51: React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array react-hooks/exhaustive-deps
Run Code Online (Sandbox Code Playgroud)
我一直找不到停止无限循环的解决方案。我想远离使用useReducer()
。我确实在https://github.com/facebook/react/issues/14920找到了这个讨论,在这里可能的解决方案是You can always // eslint-disable-next-line react-hooks/exhaustive-deps if you think you know what you're doing.
我不确定自己在做什么,所以我还没有尝试实现它。
我有这个当前设置,React hook useEffect永远/无限循环连续运行,唯一的注释是useCallback()
我不熟悉的。
我目前的使用方式useEffect()
(类似于,我一开始只想运行一次componentDidMount()
)
useEffect(() => {
fetchBusinesses();
}, []);
Run Code Online (Sandbox Code Playgroud)
const fetchBusinesses = () => {
return fetch("theURL", {method: "GET"}
)
.then(res => normalizeResponseErrors(res))
.then(res => {
return res.json();
})
.then(rcvdBusinesses => {
// some stuff
})
.catch(err => {
// some error handling
});
};
Run Code Online (Sandbox Code Playgroud)
jpe*_*nna 246
Edit 02/21/2020
Just for completeness:
useEffect
callbackuseEffect(fetchBusinesses, [])
Run Code Online (Sandbox Code Playgroud)
useEffect()
useEffect(fetchBusinesses, [])
Run Code Online (Sandbox Code Playgroud)
useCallback()
In this case, if you have dependencies in your function, you will have to include them in the useCallback
dependencies array and this will trigger the useEffect
again if the function's params change. Besides, it is a lot of boilerplate... So just pass the function directly to useEffect
as in 1. useEffect(fetchBusinesses, [])
.
useEffect(() => {
function fetchBusinesses() {
...
}
fetchBusinesses()
}, [])
Run Code Online (Sandbox Code Playgroud)
useEffect(() => {
fetchBusinesses()
}, []) // eslint-disable-line react-hooks/exhaustive-deps
Run Code Online (Sandbox Code Playgroud)
Original reply
You can set it directly as the useEffect
callback:
const fetchBusinesses = useCallback(() => {
...
}, [])
useEffect(() => {
fetchBusinesses()
}, [fetchBusinesses])
Run Code Online (Sandbox Code Playgroud)
It will trigger only once, so make sure all the function's dependencies are correctly set (same as using componentDidMount/componentWillMount...
)
Shu*_*tri 68
如果除了效果以外没有在其他地方使用fetchBusinesses方法,则可以将其移至效果中并避免出现警告
useEffect(() => {
const fetchBusinesses = () => {
return fetch("theURL", {method: "GET"}
)
.then(res => normalizeResponseErrors(res))
.then(res => {
return res.json();
})
.then(rcvdBusinesses => {
// some stuff
})
.catch(err => {
// some error handling
});
};
fetchBusinesses();
}, []);
Run Code Online (Sandbox Code Playgroud)
但是,如果在渲染之外使用fetchBusinesses,则必须注意两点
fetchBusinesses
方法传递任何问题,并且在装入过程中使用它的封闭方法,则不会有任何问题。总结一下,我想说的是,如果您在fetchBusinesses
外部使用,则可以使用useEffect
禁用规则,// eslint-disable-next-line react-hooks/exhaustive-deps
否则可以将方法移到useEffect内部
要禁用该规则,您可以这样写
useEffect(() => {
// other code
...
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
Run Code Online (Sandbox Code Playgroud)
far*_*ard 24
./src/components/BusinessesList.js
Line 51: React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array react-hooks/exhaustive-deps
Run Code Online (Sandbox Code Playgroud)
这不是JS / React错误,而是eslint(eslint-plugin-react-hooks)警告。
它告诉您钩子依赖于function fetchBusinesses
,因此您应该将其作为依赖传递。
useEffect(() => {
fetchBusinesses();
}, [fetchBusinesses]);
Run Code Online (Sandbox Code Playgroud)
如果在组件中声明了函数,则可能会导致每个渲染调用函数:
./src/components/BusinessesList.js
Line 51: React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array react-hooks/exhaustive-deps
Run Code Online (Sandbox Code Playgroud)
因为每次使用新引用重新声明函数
正确的方法是:
const Component = () => {
/*...*/
// keep function reference
const fetchBusinesses = useCallback(() => {
fetch('/api/businesses/')
.then(...)
}, [/* additional dependencies */])
useEffect(() => {
fetchBusinesses();
}, [fetchBusinesses]);
/*...*/
}
Run Code Online (Sandbox Code Playgroud)
或只是在定义功能 useEffect
更多:https://github.com/facebook/react/issues/14920
Ste*_*e L 17
React 也给出了解决方案。他们建议您使用useCallback
它将返回您的函数的记忆版本:
'fetchBusinesses' 函数使 useEffect Hook(在第 NN 行)的依赖关系在每次渲染时发生变化。要解决此问题,请将 'fetchBusinesses' 定义包装到它自己的 useCallback() Hook react-hooks/exhaustive-deps 中
useCallback
使用简单,因为它具有与useEffect
. 不同之处在于 useCallback 返回一个函数。它看起来像这样:
const fetchBusinesses = useCallback( () => {
return fetch("theURL", {method: "GET"}
)
.then(() => { /* Some stuff */ })
.catch(() => { /* Some error handling */ })
}, [/* deps */])
// We have a first effect that uses fetchBusinesses
useEffect(() => {
// Do things and then fetchBusinesses
fetchBusinesses();
}, [fetchBusinesses]);
// We can have many effects that use fetchBusinesses
useEffect(() => {
// Do other things and then fetchBusinesses
fetchBusinesses();
}, [fetchBusinesses]);
Run Code Online (Sandbox Code Playgroud)
小智 15
只需在下一行禁用 ESLint 即可;
useEffect(() => {
fetchBusinesses();
// eslint-disable-next-line
}, []);
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以像安装组件一样使用它(调用一次)。
更新
或者
const fetchBusinesses = useCallback(() => {
// Your logic in here
}, [someDeps])
useEffect(() => {
fetchBusinesses();
// No need to skip the ESLint warning
}, [fetchBusinesses]);
Run Code Online (Sandbox Code Playgroud)
每次someDeps发生变化时,都会调用 fetchBusinesses 。
Jor*_*els 11
这些警告对于查找不一致更新的组件非常有帮助:从依赖项列表中省略函数是否安全?.
但是,如果您想删除整个项目中的警告,您可以将其添加到您的 ESLint 配置中:
{
"plugins": ["react-hooks"],
"rules": {
"react-hooks/exhaustive-deps": 0
}
}
Run Code Online (Sandbox Code Playgroud)
本文是关于使用钩子获取数据的一个很好的入门:https://www.robinwieruch.de/react-hooks-fetch-data/
本质上,将 fetch 函数定义包含在其中useEffect
:
useEffect(() => {
const fetchBusinesses = () => {
return fetch("theUrl"...
// ...your fetch implementation
);
}
fetchBusinesses();
}, []);
Run Code Online (Sandbox Code Playgroud)
实际上,当您使用钩子进行开发时,这些警告非常有用。但在某些情况下,它可能会让你感到刺痛。特别是当您不需要监听依赖项更改时。
如果您不想放入fetchBusinesses
钩子的依赖项,您可以简单地将其作为参数传递给钩子的回调,并将 main 设置fetchBusinesses
为其默认值,如下所示:
useEffect((fetchBusinesses = fetchBusinesses) => {
fetchBusinesses();
}, []);
Run Code Online (Sandbox Code Playgroud)
这不是最佳实践,但在某些情况下可能很有用。
另外,正如Shubham 所写,您可以添加以下代码来告诉 ESLint 忽略对钩子的检查。
// eslint-disable-next-line react-hooks/exhaustive-deps
Run Code Online (Sandbox Code Playgroud)
你试试这个方法:
const fetchBusinesses = () => {
return fetch("theURL", {method: "GET"})
.then(res => normalizeResponseErrors(res))
.then(res => {
return res.json();
})
.then(rcvdBusinesses => {
// Some stuff
})
.catch(err => {
// Some error handling
});
};
Run Code Online (Sandbox Code Playgroud)
和
useEffect(() => {
fetchBusinesses();
});
Run Code Online (Sandbox Code Playgroud)
它适合你。
但我的建议是尝试这种方式,它也适合你。这比以前的方法要好。我这样使用它:
useEffect(() => {
const fetchBusinesses = () => {
return fetch("theURL", {method: "GET"})
.then(res => normalizeResponseErrors(res))
.then(res => {
return res.json();
})
.then(rcvdBusinesses => {
// Some stuff
})
.catch(err => {
// Some error handling
});
};
fetchBusinesses();
}, []);
Run Code Online (Sandbox Code Playgroud)
如果您根据特定 id 获取数据,则添加回调 useEffect [id]
。那么它就无法向您显示警告
React Hook useEffect has a missing dependency: 'any thing'. Either include it or remove the dependency array
const [mount, setMount] = useState(false)
const fetchBusinesses = () => {
// Function definition
}
useEffect(() => {
if(!mount) {
setMount(true);
fetchBusinesses();
}
},[fetchBusinesses]);
Run Code Online (Sandbox Code Playgroud)
这是一个非常简单的解决方案,您不需要覆盖 ESLint 警告。只需维护一个标志来检查组件是否已安装。
这不是特定于问题用例的答案,而是更一般的情况,并涵盖 useEffect 或 extract 和 import 未发出警告时的情况。useRef 场景:
有时情况是 useEffect 应该有空数组,并且您仍然想在状态的 useEffect 部分中使用,但您仍然不想将它们作为依赖项注入,您也可能尝试了 useCallback ,现在反应抱怨依赖项useCallback 和你卡住了。在某些情况下你可以使用useRef。例如:
const locationRef = useRef(location);
useEffect(()=>{
const qs = locationRef.current.search
...
},[])
Run Code Online (Sandbox Code Playgroud)
使用此技术时应小心,并注意 useRef 不会激活渲染过程。
好吧,如果你想以不同的方式研究这个问题,你只需要知道 React 有哪些选项是非的exhaustive-deps
。您不应该在效果中使用闭包函数的原因之一是在每次渲染时,它将再次重新创建/销毁。
因此,钩子中有多个 React 方法被认为是稳定且非耗尽的,您不必应用依赖useEffect
项,从而不会破坏react-hooks/exhaustive-deps
. 例如,useReducer
或 的第二个返回变量useState
是一个函数。
const [,dispatch] = useReducer(reducer, {});
useEffect(() => {
dispatch(); // Non-exhausted - ESLint won't nag about this
}, []);
Run Code Online (Sandbox Code Playgroud)
因此,您可以让所有外部依赖项与您的减速器函数中的当前依赖项共存。
const [,dispatch] = useReducer((current, update) => {
const { foobar } = update;
// Logic
return { ...current, ...update };
}, {});
const [foobar, setFoobar] = useState(false);
useEffect(() => {
dispatch({ foobar }); // non-exhausted `dispatch` function
}, [foobar]);
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
47201 次 |
最近记录: |