From 8c1bd825de0e21cdce094535cf862ca54203a4eb Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Sat, 27 Jun 2026 08:34:59 +0000 Subject: [PATCH] Keep props hidden --- .../components/forms/fields/ApiFormField.tsx | 4 +- .../components/forms/fields/TableField.tsx | 50 +++++++++++++------ src/frontend/src/forms/StockForms.tsx | 3 -- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/frontend/src/components/forms/fields/ApiFormField.tsx b/src/frontend/src/components/forms/fields/ApiFormField.tsx index 85e128a1fd..d9adc749f3 100644 --- a/src/frontend/src/components/forms/fields/ApiFormField.tsx +++ b/src/frontend/src/components/forms/fields/ApiFormField.tsx @@ -247,7 +247,9 @@ export function ApiFormField({ ); case 'tags': diff --git a/src/frontend/src/components/forms/fields/TableField.tsx b/src/frontend/src/components/forms/fields/TableField.tsx index 3e41a9f5c1..fb626a3992 100644 --- a/src/frontend/src/components/forms/fields/TableField.tsx +++ b/src/frontend/src/components/forms/fields/TableField.tsx @@ -2,8 +2,14 @@ import { t } from '@lingui/core/macro'; import { Trans } from '@lingui/react/macro'; import { Alert, Container, Group, Stack, Table, Text } from '@mantine/core'; import { IconExclamationCircle } from '@tabler/icons-react'; -import { type ReactNode, useCallback, useEffect, useMemo, useRef } from 'react'; -import type { FieldValues, UseControllerReturn } from 'react-hook-form'; +import { + type ReactNode, + memo, + useCallback, + useEffect, + useMemo, + useRef +} from 'react'; import { AddItemButton } from '@lib/components/AddItemButton'; import { identifierString } from '@lib/functions/Conversion'; @@ -84,23 +90,21 @@ export function TableFieldErrorWrapper({ ); } -export function TableField({ +function TableFieldComponent({ definition, fieldName, - control + value, + onChange, + error }: Readonly<{ definition: ApiFormFieldType; fieldName: string; - control: UseControllerReturn; + value: any; + onChange: (value: any) => void; + error?: any; }>) { - const { - field, - fieldState: { error } - } = control; - const { value } = field; - const valueRef = useRef(value); - const onChangeRef = useRef(field.onChange); + const onChangeRef = useRef(onChange); const rowIndexByIdRef = useRef(new Map()); const generatedRowIdsRef = useRef(new WeakMap()); const generatedRowIdCounterRef = useRef(0); @@ -133,7 +137,7 @@ export function TableField({ // Keep refs in sync with latest values without introducing them as deps valueRef.current = value; - onChangeRef.current = field.onChange; + onChangeRef.current = onChange; useEffect(() => { const nextRowIndexById = new Map(); @@ -223,14 +227,15 @@ export function TableField({ useWhyDidYouUpdate(`TableField-${fieldName}`, { definition, fieldName, - control + value, + error }); return ( @@ -296,7 +301,7 @@ export function TableField({ if (definition.addRow === undefined) return; const ret = definition.addRow(); if (ret) { - field.onChange([...(field.value ?? []), ret]); + onChange([...(value ?? []), ret]); } }} /> @@ -308,6 +313,19 @@ export function TableField({ ); } +export const TableField = memo( + TableFieldComponent, + (previousProps, nextProps) => { + return ( + previousProps.definition === nextProps.definition && + previousProps.fieldName === nextProps.fieldName && + previousProps.value === nextProps.value && + previousProps.onChange === nextProps.onChange && + previousProps.error === nextProps.error + ); + } +); + /* * Display an "extra" row below the main table row, for additional information. * - Each "row" can display an extra row of information below the main row diff --git a/src/frontend/src/forms/StockForms.tsx b/src/frontend/src/forms/StockForms.tsx index 7f518e50c8..8b31379648 100644 --- a/src/frontend/src/forms/StockForms.tsx +++ b/src/frontend/src/forms/StockForms.tsx @@ -57,7 +57,6 @@ import { import { Thumbnail } from '../components/images/Thumbnail'; import { StatusRenderer } from '../components/render/StatusRenderer'; import { RenderStockLocation } from '../components/render/Stock'; -import { useWhyDidYouUpdate } from '../functions/debug'; import { InvenTreeIcon } from '../functions/icons'; import { useApiFormModal, @@ -637,8 +636,6 @@ function StockOperationsRow({ }) { const rowId = props.rowId; - useWhyDidYouUpdate(`StockOperationsRow-${rowId}`, props); - const statusOptions: ApiFormFieldChoice[] = useMemo(() => { return ( StatusFilterOptions(ModelType.stockitem)()?.map((choice) => {