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
| Property | Type | Description |
|---|---|---|
| field | string | The name of the field. |
| memo | (channelValue: ChannelValue | null) => T | null | Derives the value from a ChannelValue. Defaults to returning channelValue.value.value. |
| equals | (oldValue: T | null, newValue: T | null) => boolean | Compares 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
| Property | Type | Description |
|---|---|---|
| value | T | null | The value derived by memo. |
| channelValue | ChannelValue | null | The 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>
}