Skip to main content

useMemoizedMetricField

Like useMetricField, but only re-renders the widget when a value derived from the metric changes.

A memo function derives a value from every new ChannelValue. If the derived value equals the previous one, the widget isn't re-rendered. This is useful for widgets that only display a part of the value, e.g. a number with a lower precision than the metric provides.

function useMemoizedMetricField<T>(props: {
field: string
memo?: (channelValue: ChannelValue | null) => T | null
equals?: (oldValue: T | null, newValue: T | null) => boolean
}): {value: T | null; channelValue: ChannelValue | null}

Arguments

PropertyTypeDescription
fieldstringThe name of the field.
memo(channelValue: ChannelValue | null) => T | nullDerives the value from a ChannelValue. Defaults to returning channelValue.value.value.
equals(oldValue: T | null, newValue: T | null) => booleanCompares the derived values. Defaults to a deep comparison using isEqual of lodash.

The memo and equals functions don't have to be stable, the hook always uses the latest functions.

Returns

PropertyTypeDescription
valueT | nullThe value derived by memo.
channelValueChannelValue | nullThe ChannelValue the derived value was created from.
note

The returned channelValue is only updated together with the derived value. Values that arrive without changing the derived value are not reflected in it.

Errors

The same as useMetricField.

Example

src/widgets/example/Example.tsx
import React, {useCallback} from 'react'
import {useMemoizedMetricField} from '@modbros/dashboard-sdk'
import type {ChannelValue} from '@modbros/dashboard-core'

export default function Example() {
// Only re-render when the rounded value changes
const memo = useCallback((channelValue: ChannelValue | null) => {
const value = Number(channelValue?.value.value)

return Number.isFinite(value) ? Math.round(value) : null
}, [])

const {value, channelValue} = useMemoizedMetricField({field: 'example', memo})

if (value === null || !channelValue) {
return null
}

return <span>{value} {channelValue.unit.abbreviation}</span>
}