reactjs - useState 不会在 websocket 回调处理程序中触发重新渲染
问题描述
使用 web socket( @aspnet/signalr
) 它工作正常(在组件回调中接收消息)很好,我能够在这个回调内部的组件(connection.on(“UpdateProgress”...)中接收和触发回调,它的增量计数器是状态变量(numberOfFailed)..它只触发一次渲染,我设置调试器,看到numberOfFailed
总是0。
这里有什么问题?为什么调用setNumberOfFailed
不会改变numberOfFailed
.
这是代码;
const [numberOfFailed, setNumberOfFailed] = useState(0);
const [connection, setConnection] = useState(null);
useEffect(() => {
const newConnection = new HubConnectionBuilder()
.withUrl(`${config.API_BASE_URL}update-progress`, {
transport: HttpTransportType.WebSockets,
accessTokenFactory: () => {
return `${localStorage.token}`;
},
})
.build();
setConnection(newConnection);
}, []);
useEffect(() => {
const fetchData = async () => {
if (connection) {
try {
await connection.start();
connection.onclose((error) => {
console.info('Connection Closed:', error);
});
if (connection.state === HubConnectionState.Connected) {
connection.on('UpdateProgress', (message) => {
debugger;
if (message.count) {
setTitleText(`Bildirim Gonderim Başladı, Toplam Alıcı Sayısı:${message.count}`);
} else if (message.status == 1) {
let _t = numberOfFailed + 1;
setNumberOfFailed(_t);
}
console.info('message', message);
});
}
} catch (err) {
console.log(err);
}
}
};
fetchData();
}, [connection]);
解决方案
这是因为 react 不跟踪未在 DependencyList 中明确定义的变量的更新。改变这种方式的最佳解决方案..
这就是我解决这个问题的方法;
主要思想是使用 useReducer 挂钩来更新变量并在渲染中使用它们。
const [connection, setConnection] = useState(null);
const [counts, dispatch] = useReducer(BaskentMobilReducer, INITIAL_VALUE);
useEffect(() => {
const newConnection = new HubConnectionBuilder()
.withUrl(`${config.API_BASE_URL}update-progress`, {
transport: HttpTransportType.WebSockets,
accessTokenFactory: () => {
return `${localStorage.token}`;
},
})
.build();
setConnection(newConnection);
}, []);
useEffect(() => {
const fetchData = async () => {
if (connection) {
try {
await connection.start();
connection.onclose((error) => {
console.info("Connection Closed:", error);
});
if (connection.state === HubConnectionState.Connected) {
connection.on("UpdateProgress", (message) => {
if (message.count) {
setTotalCount(message.count);
setTitleText(
`Bildirim Gonderim Başladı, Toplam Alıcı Sayısı:${message.count}`
);
} else if (message.status == 0) {
debugger;
dispatch({
type: "UPDATE_COUNTS_SUCCESS",
});
console.log("counts", counts);
} else if (message.status == 1) {
debugger;
dispatch({
type: "UPDATE_COUNTS_FAIL",
});
console.log("counts", counts);
}
console.info("message", message);
});
}
} catch (err) {
console.log(err);
}
}
};
fetchData();
}, [connection]);
推荐阅读
- linux - 从 package.json 运行 `source` 以设置脚本运行的环境变量
- mysql - Laravel 数据库问题 - 符号链接层级过多
- javascript - 如何在nodejs http模块上限制从rest服务器传入的块大小?
- c++ - 如何定义依赖于模板参数的 typedef 的 typedef
- python-3.x - 在 Google Cloud Build 中运行 python 单元测试
- php - 如何删除
wordpress 简码输出中的标记
- angular - Angular 生产版本中的无效或意外令牌错误
- php - 访问页面时多次调用 Magento 2 index.php 文件的任何原因?
- javascript - 页面加载时从下到上的图像加载
- f# - 运算符优先级解析中的左递归文法