有一个ESLint规则exhaustive-deps
,它检查Hooks的依赖项数组(例如:useEffect
)。我的问题在于,由于现在正在跟踪功能之类的事情,因此更频繁地触发useEffect的内容的影响。
当api调用位于效果内部时,这可能会产生负面影响,因为您只希望一次调用该API。
我可以进一步分解效果,也许对dep数组有帮助...也许不是...
如何防止内容被触发超出所需范围? 对我来说,为了防止对API服务的额外调用,我要么需要忽略lint规则(否!),要么对我的代码进行更多检查,并对状态进行本地设置:
防止多次触发会话和api调用的示例:
useEffect(() => {
if (!saveValues) { // is this an anti-pattern?
return;
}
if (!sessionId && !wasSaving && savingForm) {
initSession().then(() => { // 1st call to session service to get Id
setSendRequest(true); // set local state that it's safe to send API request because I have my session ready
});
} else if (sendRequest && sessionId) {
setSendRequest(false); // immediately set local state back to false so the previous block doesnt fire.
try {
const fields = userFields
.filter(field => !isEmpty(saveValues[field.name]))
.map(field => {
name: field.name,
value,
};
);
insertUser({ sessionId, fields, config, newRoles }) // here's my API call now
.then(() => saveSession(sessionId)) // 2nd call to session service req'd
} catch (err) {
const message = err.message.split('desc = ')[1];
setSaveRequestError(message);
setSavingForm(false);
setSaveModalOpen(false);
quitSession(sessionId);
}
}
return () => {
if (sessionId) {
quitSession(sessionId);
}
};
}, [
initSession,
insertUser,
quitSession,
roles.rolesList,
saveSession,
saveValues,
savingForm,
sendRequest,
sessionId,
userFields,
wasSaving,
]);
作为旁注,有趣的是,状态钩子(如setSaveRequestError,setSavingForm)不会显示在dep数组中...
答案 0 :(得分:0)
答案 1 :(得分:0)
如果您只是想避免再次执行它(并且您不想传递空的dep数组),则useRef是您的朋友,因为它不会重新呈现组件(不是状态):
let hasBeenExecuted = useRef(false);
//In effect
if(!hasBeenExecuted.current) {
// Do stuff
hasBeenExecuted.current = true
}
答案 2 :(得分:0)
我很抱歉迟到了。这个仓库就是为了解决这个问题。
useWatch(() => {
// your logic
}, [your dependency])
巧妙完美地解决这个问题。
答案 3 :(得分:-2)
useEffect。
注意:useEffect(()=> {},[dependency1,dependency2 ...])
如果只希望在组件最初加载时才调用useEffect中的代码,请将空数组作为依赖项传递。