Refactor ObjectDisplay and ObjectTable components for improved subscription handling
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good

- Updated ObjectDisplay to subscribe to object updates based on the object ID, enhancing responsiveness to changes.
- Refactored ObjectTable to streamline subscription logic, ensuring real-time updates are managed more efficiently and reducing unnecessary re-renders.
This commit is contained in:
Tom Butcher 2026-07-26 19:26:52 +01:00
parent 1a68456be6
commit c6ec643a2f
2 changed files with 39 additions and 26 deletions

View File

@ -86,12 +86,18 @@ const ObjectDisplay = ({
[fetchSpotlightData, isMinimalObject, objectType] [fetchSpotlightData, isMinimalObject, objectType]
) )
// Subscribe to object updates when component mounts const subscriptionObjectId = getStringId(object)
// Subscribe to object updates when the object ID changes
useEffect(() => { useEffect(() => {
const id = getStringId(object) if (
if (isValidId(id) && objectType && connected && token != null) { isValidId(subscriptionObjectId) &&
objectType &&
connected &&
token != null
) {
const objectUpdatesUnsubscribe = subscribeToObjectUpdates( const objectUpdatesUnsubscribe = subscribeToObjectUpdates(
id, subscriptionObjectId,
objectType, objectType,
updateObjectEventHandler updateObjectEventHandler
) )
@ -101,14 +107,13 @@ const ObjectDisplay = ({
} }
} }
}, [ }, [
object, subscriptionObjectId,
objectType, objectType,
subscribeToObjectUpdates, subscribeToObjectUpdates,
connected, connected,
token, token,
updateObjectEventHandler, updateObjectEventHandler,
isValidId, isValidId
getStringId
]) ])
// Update local state when object prop changes // Update local state when object prop changes

View File

@ -183,6 +183,12 @@ const ObjectTable = forwardRef(
const unsubscribesRef = useRef([]) const unsubscribesRef = useRef([])
const updateEventHandlerRef = useRef() const updateEventHandlerRef = useRef()
const subscribeToObjectTypeUpdatesRef = useRef(null) const subscribeToObjectTypeUpdatesRef = useRef(null)
const subscribedTypeRef = useRef(null)
const newEventHandlerRef = useRef()
const subscriptionFilterRef = useRef()
const subscribeToObjectTypeUpdatesFnRef = useRef(
subscribeToObjectTypeUpdates
)
const prevValuesRef = useRef({ type, masterFilter }) const prevValuesRef = useRef({ type, masterFilter })
const rowActions = const rowActions =
@ -611,6 +617,10 @@ const ObjectTable = forwardRef(
return { ...active, ...masterFilter } return { ...active, ...masterFilter }
}, [sidebarFilter, masterFilter]) }, [sidebarFilter, masterFilter])
newEventHandlerRef.current = newEventHandler
subscriptionFilterRef.current = subscriptionFilter
subscribeToObjectTypeUpdatesFnRef.current = subscribeToObjectTypeUpdates
// Subscribe to real-time updates for all items // Subscribe to real-time updates for all items
useEffect(() => { useEffect(() => {
if (pages.length > 0 && connected == true) { if (pages.length > 0 && connected == true) {
@ -682,28 +692,26 @@ const ObjectTable = forwardRef(
}, [connected]) }, [connected])
useEffect(() => { useEffect(() => {
if (connected == true) { if (connected !== true) return
const unsubscribe = subscribeToObjectTypeUpdates( if (subscribedTypeRef.current === type) return
type,
subscriptionFilter,
newEventHandler
)
subscribeToObjectTypeUpdatesRef.current = unsubscribe
return () => { const unsubscribe = subscribeToObjectTypeUpdatesFnRef.current(
if (unsubscribe) unsubscribe() type,
if (subscribeToObjectTypeUpdatesRef.current === unsubscribe) { subscriptionFilterRef.current,
subscribeToObjectTypeUpdatesRef.current = null (params) => newEventHandlerRef.current(params)
} )
subscribeToObjectTypeUpdatesRef.current = unsubscribe
subscribedTypeRef.current = type
return () => {
if (unsubscribe) unsubscribe()
if (subscribeToObjectTypeUpdatesRef.current === unsubscribe) {
subscribeToObjectTypeUpdatesRef.current = null
}
if (subscribedTypeRef.current === type) {
subscribedTypeRef.current = null
} }
} }
}, [ }, [type, connected])
type,
subscriptionFilter,
subscribeToObjectTypeUpdates,
connected,
newEventHandler
])
const updateData = useCallback( const updateData = useCallback(
(id, updatedData) => { (id, updatedData) => {