如何阻止 useEffect 发出如此多的请求?空依赖不起作用
How to stop useEffect from making so many requests? Empty Dependencies don't work
我有一个更新状态的组件,但我遇到了问题
我已声明状态
const [data, setData] = useState([]);
然后在我的useEffect中我是
useEffect(() => {
const fetchData = async () => {
await axios
.get(
API_URL,
{
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY
},
params:{
"titleId": id
}
}
)
.then((response) => {
setData(response.data.Item);
})
.catch((err) => {
console.error("API call error:", err.message);
});
}
fetchData();
}, [data, id])
如果我在我的依赖项中声明“数据”,我会得到一个无休止的请求循环,这显然是不好的。但是如果我从依赖项中遗漏 'data' 它什么也没有显示,尽管我在我的网络选项卡中成功检索它,即使我在 div 标签中 {JSON.styringify(data)}
我得到 json 内容太多。所以信息在 DOM 中,但它没有更新组件
我该怎么做才能发出初始请求来加载数据而不是成千上万的数据?
我试过以下方法:
- 回调函数上的 setTimeout
- 使用 return (() => { callbackFunction.cancel(); })
的 isCancelled 方式
- 还有一种中止方法可以做到这一点,但我无法弄清楚。我见过的每个例子都是针对 class 组件
抱歉,代码含糊不清。如果没有大量编码和 API,我无法复制它。提前致谢
做这样的事情,如果有帮助的话。我也用了 async/await
所以你可以检查一下。
const App = () => {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get(API_URL, {
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
params: {
titleId: id,
},
});
setData(response.data.Item);
} catch (err) {
console.error('API call error:', err.message);
}
};
fetchData();
}, [id]);
if (!data.length) return null;
return <p>Yes, I have data</p>;
};
您想设置状态,然后检查是否不同。我为此使用了一个自定义挂钩,它使用了 useRef 挂钩:
export function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
const prevData = usePrevious(data);
我不知道你的数据是什么样的,但从中构建一个条件。在你的 useEffect 中你需要像这样的东西:
if (data !== prevData) fetchData()
或
if (data.id !== prevData.id) fetchData()
然后您将添加 prevData 到您的依赖项:
[data, prevData, id]
显然你会得到一个无限循环!
您正在更新 useEffect 中的 data,这意味着每次 data 更改时,都会再次触发 useEffect 等等!
你应该做的是改变你的依赖关系 depending 例如:
const [data, setData] = useState([])
const [fetchAgain, setFetchAgain] = useState(false)
useEffect(()=> {
fetchData();
}, [])
useEffect(() => {
if(fetchAgain) {
setFetchAgain(false)
fetchData();
}
}, [fetchAgain])
现在每次你想再次获取数据时你需要将 fetchAgain 更新为 true
所以 useEffects 与依赖一起工作。
具有依赖性 - 在更改依赖值时 useEffect 将触发
useEffect(() => {
// code
}, [dependency])
带空括号 - 将在组件首字母处触发
useEffect(() => {
// code
}, [])
没有依赖项和括号 - 将在每次状态更改时触发
useEffect(() => {
// code
})
我有一个更新状态的组件,但我遇到了问题
我已声明状态
const [data, setData] = useState([]);
然后在我的useEffect中我是
useEffect(() => {
const fetchData = async () => {
await axios
.get(
API_URL,
{
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY
},
params:{
"titleId": id
}
}
)
.then((response) => {
setData(response.data.Item);
})
.catch((err) => {
console.error("API call error:", err.message);
});
}
fetchData();
}, [data, id])
如果我在我的依赖项中声明“数据”,我会得到一个无休止的请求循环,这显然是不好的。但是如果我从依赖项中遗漏 'data' 它什么也没有显示,尽管我在我的网络选项卡中成功检索它,即使我在 div 标签中 {JSON.styringify(data)}
我得到 json 内容太多。所以信息在 DOM 中,但它没有更新组件
我该怎么做才能发出初始请求来加载数据而不是成千上万的数据?
我试过以下方法:
- 回调函数上的 setTimeout
- 使用 return (() => { callbackFunction.cancel(); }) 的 isCancelled 方式
- 还有一种中止方法可以做到这一点,但我无法弄清楚。我见过的每个例子都是针对 class 组件
抱歉,代码含糊不清。如果没有大量编码和 API,我无法复制它。提前致谢
做这样的事情,如果有帮助的话。我也用了 async/await
所以你可以检查一下。
const App = () => {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
try {
const response = await axios.get(API_URL, {
headers: {
'Content-Type': 'application/json',
'X-API-KEY': API_KEY,
},
params: {
titleId: id,
},
});
setData(response.data.Item);
} catch (err) {
console.error('API call error:', err.message);
}
};
fetchData();
}, [id]);
if (!data.length) return null;
return <p>Yes, I have data</p>;
};
您想设置状态,然后检查是否不同。我为此使用了一个自定义挂钩,它使用了 useRef 挂钩:
export function usePrevious(value) {
const ref = useRef();
useEffect(() => {
ref.current = value;
}, [value]);
return ref.current;
}
const prevData = usePrevious(data);
我不知道你的数据是什么样的,但从中构建一个条件。在你的 useEffect 中你需要像这样的东西:
if (data !== prevData) fetchData()
或
if (data.id !== prevData.id) fetchData()
然后您将添加 prevData 到您的依赖项:
[data, prevData, id]
显然你会得到一个无限循环! 您正在更新 useEffect 中的 data,这意味着每次 data 更改时,都会再次触发 useEffect 等等! 你应该做的是改变你的依赖关系 depending 例如:
const [data, setData] = useState([])
const [fetchAgain, setFetchAgain] = useState(false)
useEffect(()=> {
fetchData();
}, [])
useEffect(() => {
if(fetchAgain) {
setFetchAgain(false)
fetchData();
}
}, [fetchAgain])
现在每次你想再次获取数据时你需要将 fetchAgain 更新为 true
所以 useEffects 与依赖一起工作。
具有依赖性 - 在更改依赖值时 useEffect 将触发
useEffect(() => {
// code
}, [dependency])
带空括号 - 将在组件首字母处触发
useEffect(() => {
// code
}, [])
没有依赖项和括号 - 将在每次状态更改时触发
useEffect(() => {
// code
})