reactjs - 为什么在 useEffect 中侦听套接字事件时对服务器有多个请求?
问题描述
尽管在节点 js 服务器中只发出一个事件,但我收到了多个请求。我只想在服务器发出事件时重新渲染我的组件,以便通知用户已成功完成。这是我从服务器获取数据的自定义钩子:
import { useCallback, useState } from 'react';
export const useFetch = () => {
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
const request = useCallback(async (url, method='GET', body = null, headers = {}) => {
setLoading(true)
try {
if(body) {
body = JSON.stringify(body)
headers['Content-Type'] = 'application/json'
}
const response = await fetch(url, {method, body, headers})
const data = await response.json()
if(!response.ok) {
throw new Error(data.msg || 'Что-то пошло не так!')
}
setLoading(false)
return data
} catch (e) {
setLoading(false)
setError(e.message)
throw e
}
}, [])
const clearError = () => setError(null)
return [loading, error, request, clearError]
}
这是我的 home.js 文件代码,我从服务器获取数据:
const Home = () => {
const [loading, error, request, clearError] = useFetch()
const [tables, setTables] = useState(null)
useEffect(() => {
const handleFetchTables = async() => {
try {
const data = await request('/api/table/getAllTablesForCash')
setTables(data)
} catch (_) {
console.log(_.message)
clearError()
}
}
handleFetchTables()
socketIO.on('new_order_finished', async() => handleFetchTables())
socketIO.on('order_closed', async() => handleFetchTables())
}, [request])
const handleTables = () => {
if(loading) return <CustomSpinner />
if(error) return <NetworkError />
return tables && (
tables.length ? (
<div style={styles.main}>
{
tables.reverse().map((t, i) => {
return (
<TableCard key={i} t={t} />
)
})
}
</div>
) : (
<EmptyBag />
)
)
}
return (
<div style={styles.container}>
<HomeHeader />
{handleTables()}
</div>
)
}
解决方案
在您的 home.js 中,每次请求发生变化时都会调用 useEffect。useEffect 块包含订阅套接字发出的事件的代码。因此,每次调用 useEffect 以更改“请求”时,您都在为该事件创建另一个订阅者。所以如果一个事件被触发,它会多次调用订阅的函数。
尝试从当前 useEffect 中删除 [request] 部分。如果您真的想根据“请求”对象中的更改做某事,请使用另一个 useEffect 块并且不要将事件订阅者放入其中。或者尝试在当前 useEffect 块的开头取消订阅,但这不是一个好的解决方案。希望这能解决您的问题
推荐阅读
- apache-spark - pyspark 数据帧中的完全外连接
- python - 尝试引用复合外键时出现 sqlalchemy.exc.ProgrammingError
- xml - 有没有办法使用 Oxygen 一次更改多个 XML 文件中的日期格式?
- c# - Xamarin,Android-MySQL 连接错误
- javafx - 如何使用代码(不是 FXML)在 JavaFX 中为 ImageView 添加填充或边距
- android - 我的折叠栏图像没有滚动
- python - Microsoft Outlook 图形事件 api:如何获取不同的时区?
- amazon-web-services - AWS弹性beantalk应用程序上的https超时
- java - 单元测试的 Hibernate 覆盖策略
- c - 带有双指针的 C 内存泄漏