如何在自定义挂钩中修复 "useEffect has a missing dependency"
How do I fix "useEffect has a missing dependency" in custom hook
我正在使用自定义挂钩从 API 中提取一些数据,以便在一组 React 函数组件中使用。然而,esLint 抛出了一个可爱的警告:
React Hook useEffect has a missing dependency: 'fetchFromAPI'. Either
include it or remove the dependency array.
我不认为它是依赖项,因为它在 useFetch()
本身内部。我需要这样做,因为我正在使用 await
。我究竟做错了什么?可以只关闭此行的警告吗?还是我应该使用更规范的语法?
function useFetch (url) {
const [data, setData] = useState(null);
async function fetchFromAPI() {
const json = await( await fetch(url) ).json();
setData(json);
}
useEffect(() => {fetchFromAPI()},[url]);
return data;
};
export {
useFetch
};
在自定义效果之外声明它,传递 url
作为参数,return
json
设置在 useEffect
中
async function fetchFromAPI(url) {
const json = await( await fetch(url) ).json();
return json
}
function useFetch (url) {
const [data, setData] = useState(null);
useEffect(() => {
setData(fetchFromAPI(url))
},[url]);
return data;
};
或者直接在里面useEffect
function useFetch (url) {
const [data, setData] = useState(null);
useEffect(() => {
async function fetchFromAPI() {
const json = await( await fetch(url) ).json();
return json
}
setData(fetchFromAPI())
},[url]);
return data;
};
我建议你在 useEffect 本身中定义异步函数:
function useFetch (url) {
const [data, setData] = useState(null);
useEffect(() => {
async function fetchFromAPI() {
const json = await( await fetch(url) ).json();
setData(json);
}
fetchFromAPI()
},[url]);
return data;
};
您可以查看来自 doc faqs 的有效示例,它在 useEffect 本身内部使用了异步函数:
function ProductPage({ productId }) {
const [product, setProduct] = useState(null);
useEffect(() => {
// By moving this function inside the effect,
// we can clearly see the values it uses.
async function fetchProduct() {
const response = await fetch('http://myapi/product' + productId);
const json = await response.json();
setProduct(json);
}
fetchProduct();
}, [productId]); // ✅ Valid because our effect only uses productId
// ...
}
只要把你的函数移到 useEffect 里面,一切都会好起来的:
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState(null);
useEffect(() => {
async function fetchFromAPI() {
const json = await (await fetch(url)).json();
setData(json);
}
fetchFromAPI();
}, [url]);
return data;
}
export { useFetch };
async function fetchFromAPI(url) {
return ( await fetch(url) ).json();
}
function useFetch (url) {
const [data, setData] = useState(null);
useEffect(() => {
fetchFromAPI(url).then(setData);
}, [url, setData, fetchFromAPI]);
return data;
};
export {
useFetch
};
- 你可以稍微改变一下然后提取
fetchFromAPI
,因为不是每次useFetch调用都创建,也有利于单一职责。
- 如果您非常了解这段代码,当然您可以关闭当前行的 linting,或者您可以添加其余的
setData
和 fetchFromAPI
参数。并且完全按照这个顺序。因为在重新渲染时,参数比较从第一个参数开始到最后一个,最好将更改最多的参数放在第一位,因为每次更改下一个参数时都不会检查未更改的参数,所以如果第一次更改,useEffect
不要'需要检查其他人并提前调用传递的函数
我正在使用自定义挂钩从 API 中提取一些数据,以便在一组 React 函数组件中使用。然而,esLint 抛出了一个可爱的警告:
React Hook useEffect has a missing dependency: 'fetchFromAPI'. Either include it or remove the dependency array.
我不认为它是依赖项,因为它在 useFetch()
本身内部。我需要这样做,因为我正在使用 await
。我究竟做错了什么?可以只关闭此行的警告吗?还是我应该使用更规范的语法?
function useFetch (url) {
const [data, setData] = useState(null);
async function fetchFromAPI() {
const json = await( await fetch(url) ).json();
setData(json);
}
useEffect(() => {fetchFromAPI()},[url]);
return data;
};
export {
useFetch
};
在自定义效果之外声明它,传递 url
作为参数,return
json
设置在 useEffect
async function fetchFromAPI(url) {
const json = await( await fetch(url) ).json();
return json
}
function useFetch (url) {
const [data, setData] = useState(null);
useEffect(() => {
setData(fetchFromAPI(url))
},[url]);
return data;
};
或者直接在里面useEffect
function useFetch (url) {
const [data, setData] = useState(null);
useEffect(() => {
async function fetchFromAPI() {
const json = await( await fetch(url) ).json();
return json
}
setData(fetchFromAPI())
},[url]);
return data;
};
我建议你在 useEffect 本身中定义异步函数:
function useFetch (url) {
const [data, setData] = useState(null);
useEffect(() => {
async function fetchFromAPI() {
const json = await( await fetch(url) ).json();
setData(json);
}
fetchFromAPI()
},[url]);
return data;
};
您可以查看来自 doc faqs 的有效示例,它在 useEffect 本身内部使用了异步函数:
function ProductPage({ productId }) {
const [product, setProduct] = useState(null);
useEffect(() => {
// By moving this function inside the effect,
// we can clearly see the values it uses.
async function fetchProduct() {
const response = await fetch('http://myapi/product' + productId);
const json = await response.json();
setProduct(json);
}
fetchProduct();
}, [productId]); // ✅ Valid because our effect only uses productId
// ...
}
只要把你的函数移到 useEffect 里面,一切都会好起来的:
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState(null);
useEffect(() => {
async function fetchFromAPI() {
const json = await (await fetch(url)).json();
setData(json);
}
fetchFromAPI();
}, [url]);
return data;
}
export { useFetch };
async function fetchFromAPI(url) {
return ( await fetch(url) ).json();
}
function useFetch (url) {
const [data, setData] = useState(null);
useEffect(() => {
fetchFromAPI(url).then(setData);
}, [url, setData, fetchFromAPI]);
return data;
};
export {
useFetch
};
- 你可以稍微改变一下然后提取
fetchFromAPI
,因为不是每次useFetch调用都创建,也有利于单一职责。 - 如果您非常了解这段代码,当然您可以关闭当前行的 linting,或者您可以添加其余的
setData
和fetchFromAPI
参数。并且完全按照这个顺序。因为在重新渲染时,参数比较从第一个参数开始到最后一个,最好将更改最多的参数放在第一位,因为每次更改下一个参数时都不会检查未更改的参数,所以如果第一次更改,useEffect
不要'需要检查其他人并提前调用传递的函数