mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-07-20 18:59:01 +03:00
Replace react-tracked and react-use-websocket with useSyncExternalStore (#22386)
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions
* refactor websockets to remove react-tracked
react 19 removed useReducer eager bailout, which broke react-tracked.
react-tracked works by wrapping state in a JavaScript Proxy. When a component reads state.someField, the proxy records that access. On the next state update, it compares only the fields each component actually touched and skips re-renders if those fields are unchanged. Under the hood, this relies on useReducer — and in React 18, useReducer had an "eager bail-out" that short-circuited rendering when the new state was === to the old state. React 19 removed that optimization, so every dispatch now schedules a render regardless, and the proxy comparison runs too late to prevent it.
useSyncExternalStore is a React primitive (added in 18, stable in 19) designed for exactly this pattern: subscribing to an external store:
useSyncExternalStore(
subscribe, // (listener) => unsubscribe — called when the store changes
getSnapshot // () => value — returns the current value for this subscriber
)
React calls getSnapshot during render and compares the result with Object.is. If the value is the same reference, the component bails out — no re-render. The key difference from react-tracked is that this bail-out is built into React's reconciler, not bolted on via proxy tricks and useReducer.
The per-topic subscription model makes this efficient. Instead of one global store where every subscriber has to check if their fields changed, each useWs("some/topic", ...) call subscribes only to that topic's listener set. When a message arrives for front_door/detect/state, only components subscribed to that exact topic get their listener fired → React calls their getSnapshot → Object.is compares the value → bail-out if unchanged. Components watching back_yard/detect/state are never even notified.
* remove react-tracked and react-use-websocket
* refactor usePolygonStates to use ws topic subscription
* fix TimeAgo refresh interval always returning 1s due to unit mismatch (seconds vs milliseconds)
older events now correctly refresh every minute/hour instead of every second
* simplify
* clean up
* don't resend onconnect
* clean up
* remove patch
This commit is contained in:
@@ -1,23 +0,0 @@
|
||||
diff --git a/node_modules/react-use-websocket/dist/lib/use-websocket.js b/node_modules/react-use-websocket/dist/lib/use-websocket.js
|
||||
index f01db48..b30aff2 100644
|
||||
--- a/node_modules/react-use-websocket/dist/lib/use-websocket.js
|
||||
+++ b/node_modules/react-use-websocket/dist/lib/use-websocket.js
|
||||
@@ -139,15 +139,15 @@ var useWebSocket = function (url, options, connect) {
|
||||
}
|
||||
protectedSetLastMessage = function (message) {
|
||||
if (!expectClose_1) {
|
||||
- (0, react_dom_1.flushSync)(function () { return setLastMessage(message); });
|
||||
+ setLastMessage(message);
|
||||
}
|
||||
};
|
||||
protectedSetReadyState = function (state) {
|
||||
if (!expectClose_1) {
|
||||
- (0, react_dom_1.flushSync)(function () { return setReadyState(function (prev) {
|
||||
+ setReadyState(function (prev) {
|
||||
var _a;
|
||||
return (__assign(__assign({}, prev), (convertedUrl.current && (_a = {}, _a[convertedUrl.current] = state, _a))));
|
||||
- }); });
|
||||
+ });
|
||||
}
|
||||
};
|
||||
if (createOrJoin_1) {
|
||||
Reference in New Issue
Block a user