Enhance ObjectSelect component with value identity tracking and loading optimizations

- Introduced valueRef and prevValueIdentityRef to track changes in selected object values.
- Added getValueIdentity function to normalize object values for comparison.
- Updated treeSelectValue handling to prevent unnecessary fetches and improve performance.
- Enhanced useEffect dependencies for accurate value change detection and logging.
This commit is contained in:
Tom Butcher 2025-12-07 02:42:10 +00:00
parent c10daf008e
commit 2879b8648d

View File

@ -47,11 +47,23 @@ const ObjectSelect = ({
const [objectList, setObjectList] = useState([])
const [treeSelectValue, setTreeSelectValue] = useState(null)
const [initialLoading, setInitialLoading] = useState(true)
const valueRef = useRef(null)
// Refs to track value changes
const prevValueRef = useRef(value)
const isInternalChangeRef = useRef(false)
// Normalize a value to an identity string so we can detect in-place _id updates
const getValueIdentity = useCallback((val) => {
if (val && typeof val === 'object') {
if (val._id) return String(val._id)
if (val.value && typeof val.value === 'object' && val.value._id)
return String(val.value._id)
}
return JSON.stringify(val)
}, [])
const prevValueIdentityRef = useRef(getValueIdentity(value))
// Utility function to check if object only contains _id
const isMinimalObject = useCallback((obj) => {
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) {
@ -162,7 +174,6 @@ const ObjectSelect = ({
const buildTreeData = useCallback(
(data, pIdx = 0, parentKeys = [], filterPath = []) => {
if (!data || !Array.isArray(data)) return []
console.log(data, pIdx, properties.length)
// If we are past the grouping properties, these are leaf objects
if (pIdx >= properties.length) {
return data.map((object) => {
@ -180,6 +191,7 @@ const ObjectSelect = ({
objectType={type}
objectData={object}
isEditing={false}
style={{ top: '-0.5px' }}
/>
</div>
),
@ -342,12 +354,14 @@ const ObjectSelect = ({
value &&
typeof value === 'object' &&
value !== null &&
!initialized &&
valueRef.current !== value &&
type != 'unknown'
) {
console.log('fetching full object', value)
valueRef.current = value
// Check if value is a minimal object and fetch full object if needed
const fullValue = await fetchFullObjectIfNeeded(value)
console.log('fullValue', fullValue)
// Build a new filter from value's properties that are in the properties list
const valueFilter = { ...filter }
properties.forEach((prop) => {
@ -370,7 +384,8 @@ const ObjectSelect = ({
})
// Fetch with the new filter
handleFetchObjectsProperties(valueFilter)
setTreeSelectValue(fullValue._id)
console.log('setting treeSelectValue', valueRef.current._id)
setTreeSelectValue(valueRef.current._id)
setInitialized(true)
return
}
@ -410,6 +425,10 @@ const ObjectSelect = ({
const prevValuesRef = useRef({ type, masterFilter })
useEffect(() => {
console.log('treeSelectValue', treeSelectValue)
}, [treeSelectValue])
useEffect(() => {
const prevValues = prevValuesRef.current
@ -433,8 +452,9 @@ const ObjectSelect = ({
useEffect(() => {
// Check if value has actually changed
const currentValueIdentity = getValueIdentity(value)
const hasValueChanged =
JSON.stringify(prevValueRef.current) !== JSON.stringify(value)
prevValueIdentityRef.current !== currentValueIdentity
if (hasValueChanged) {
const changeSource = isInternalChangeRef.current ? 'internal' : 'external'
@ -451,8 +471,9 @@ const ObjectSelect = ({
// Update the previous value reference
prevValueRef.current = value
prevValueIdentityRef.current = currentValueIdentity
}
}, [value])
}, [value, getValueIdentity])
const placeholder = useMemo(
() =>