Fix gRPC stream handling after UI refactor.

This moves the onMessage handler out of useEffect and it fixes
appending the the array. The .unshift() method does not work
well using React.useState. It would prepend, but since it would not
change the array (it adds an item to the array), the update would
not propagate.
This commit is contained in:
Orne Brocaar 2023-07-27 16:38:20 +01:00
parent 6f1638e87a
commit 651fcfce43
4 changed files with 36 additions and 47 deletions

View File

@ -101,6 +101,7 @@ class InternalStore extends EventEmitter {
return () => { return () => {
if (stream) { if (stream) {
console.log("Cancelling gRPC stream");
stream.cancel(); stream.cancel();
} }
}; };

View File

@ -1,4 +1,4 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState, useCallback } from "react";
import { Device } from "@chirpstack/chirpstack-api-grpc-web/api/device_pb"; import { Device } from "@chirpstack/chirpstack-api-grpc-web/api/device_pb";
import { StreamDeviceEventsRequest, LogItem } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb"; import { StreamDeviceEventsRequest, LogItem } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb";
@ -13,17 +13,16 @@ interface IProps {
function DeviceEvents(props: IProps) { function DeviceEvents(props: IProps) {
const [events, setEvents] = useState<LogItem[]>([]); const [events, setEvents] = useState<LogItem[]>([]);
const onMessage = useCallback((l: LogItem) => {
setEvents(e => {
if (e.length === 0 || parseInt(l.getId().replace("-", "")) > parseInt(e[0].getId().replace("-", ""))) {
return [l, ...e];
}
return e;
});
}, []);
useEffect(() => { useEffect(() => {
const onMessage = (l: LogItem) => {
setEvents(e => {
if (e.length === 0 || parseInt(l.getId().replace("-", "")) > parseInt(e[0].getId().replace("-", ""))) {
e.unshift(l);
}
return e;
});
};
let req = new StreamDeviceEventsRequest(); let req = new StreamDeviceEventsRequest();
req.setDevEui(props.device.getDevEui()); req.setDevEui(props.device.getDevEui());
@ -32,7 +31,7 @@ function DeviceEvents(props: IProps) {
return () => { return () => {
cancelFunc(); cancelFunc();
}; };
}, [props]); }, [props, onMessage]);
return <LogTable logs={events} />; return <LogTable logs={events} />;
} }

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect, useCallback } from "react";
import { Device } from "@chirpstack/chirpstack-api-grpc-web/api/device_pb"; import { Device } from "@chirpstack/chirpstack-api-grpc-web/api/device_pb";
import { StreamDeviceFramesRequest, LogItem } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb"; import { StreamDeviceFramesRequest, LogItem } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb";
@ -13,26 +13,20 @@ interface IProps {
function DeviceFrames(props: IProps) { function DeviceFrames(props: IProps) {
const [frames, setFrames] = useState<LogItem[]>([]); const [frames, setFrames] = useState<LogItem[]>([]);
const onMessage = useCallback((l: LogItem) => {
setFrames(f => {
if (f.length === 0 || parseInt(l.getId().replace("-", "")) > parseInt(f[0].getId().replace("-", ""))) {
return [l, ...f];
}
return f;
});
}, []);
useEffect(() => { useEffect(() => {
const onMessage = (l: LogItem) => {
setFrames(f => {
if (f.length === 0 || parseInt(l.getId().replace("-", "")) > parseInt(f[0].getId().replace("-", ""))) {
f.unshift(l);
}
return f;
});
};
let req = new StreamDeviceFramesRequest(); let req = new StreamDeviceFramesRequest();
req.setDevEui(props.device.getDevEui()); req.setDevEui(props.device.getDevEui());
return InternalStore.streamDeviceFrames(req, onMessage);
let cancelFunc = InternalStore.streamDeviceFrames(req, onMessage); }, [props, onMessage]);
return () => {
cancelFunc();
};
}, [props]);
return <LogTable logs={frames} />; return <LogTable logs={frames} />;
} }

View File

@ -1,4 +1,4 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect, useCallback } from "react";
import { Gateway } from "@chirpstack/chirpstack-api-grpc-web/api/gateway_pb"; import { Gateway } from "@chirpstack/chirpstack-api-grpc-web/api/gateway_pb";
import { StreamGatewayFramesRequest, LogItem } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb"; import { StreamGatewayFramesRequest, LogItem } from "@chirpstack/chirpstack-api-grpc-web/api/internal_pb";
@ -13,25 +13,20 @@ interface IProps {
function GatewayFrames(props: IProps) { function GatewayFrames(props: IProps) {
const [frames, setFrames] = useState<LogItem[]>([]); const [frames, setFrames] = useState<LogItem[]>([]);
useEffect(() => { const onMessage = useCallback((l: LogItem) => {
const onMessage = (l: LogItem) => { setFrames(f => {
setFrames(f => { if (f.length === 0 || parseInt(l.getId().replace("-", "")) > parseInt(f[0].getId().replace("-", ""))) {
if (f.length === 0 || parseInt(l.getId().replace("-", "")) > parseInt(f[0].getId().replace("-", ""))) { return [l, ...f];
f.unshift(l); }
} return f;
return f; });
}); }, []);
};
useEffect(() => {
let req = new StreamGatewayFramesRequest(); let req = new StreamGatewayFramesRequest();
req.setGatewayId(props.gateway.getGatewayId()); req.setGatewayId(props.gateway.getGatewayId());
return InternalStore.streamGatewayFrames(req, onMessage);
let cancelFunc = InternalStore.streamGatewayFrames(req, onMessage); }, [props, onMessage]);
return () => {
cancelFunc();
};
}, [props]);
return <LogTable logs={frames} />; return <LogTable logs={frames} />;
} }