diff --git a/frontend/src/components/dashboard/ActionQueueCard.tsx b/frontend/src/components/dashboard/ActionQueueCard.tsx
index 700b9a67..f802a61a 100644
--- a/frontend/src/components/dashboard/ActionQueueCard.tsx
+++ b/frontend/src/components/dashboard/ActionQueueCard.tsx
@@ -8,7 +8,7 @@
* about why each action is needed and what happens if they don't do it.
*/
-import React, { useState } from 'react';
+import React, { useState, useMemo } from 'react';
import {
FileText,
AlertCircle,
@@ -71,9 +71,17 @@ function ActionItemCard({
const { t } = useTranslation('reasoning');
// Translate reasoning_data (or fallback to deprecated text fields)
- const { reasoning, consequence, severity } = action.reasoning_data
- ? formatPOAction(action.reasoning_data)
- : { reasoning: action.reasoning || '', consequence: action.consequence || '', severity: '' };
+ // Memoize to prevent undefined values from being created on each render
+ const { reasoning, consequence, severity } = useMemo(() => {
+ if (action.reasoning_data) {
+ return formatPOAction(action.reasoning_data);
+ }
+ return {
+ reasoning: action.reasoning || '',
+ consequence: action.consequence || '',
+ severity: ''
+ };
+ }, [action.reasoning_data, action.reasoning, action.consequence, formatPOAction]);
return (
{
+ if (item.reasoning_data) {
+ return formatBatchAction(item.reasoning_data);
+ }
+ return { reasoning: item.reasoning || '' };
+ }, [item.reasoning_data, item.reasoning, formatBatchAction]);
const startTime = item.plannedStartTime
? new Date(item.plannedStartTime).toLocaleTimeString('en-US', {
diff --git a/frontend/src/hooks/useReasoningTranslation.ts b/frontend/src/hooks/useReasoningTranslation.ts
index d1652643..ce4476e6 100644
--- a/frontend/src/hooks/useReasoningTranslation.ts
+++ b/frontend/src/hooks/useReasoningTranslation.ts
@@ -5,6 +5,7 @@
* user-friendly, multilingual text for the JTBD dashboard.
*/
+import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
export interface ReasoningData {
@@ -135,7 +136,7 @@ export function useReasoningTranslation() {
export function useReasoningFormatter() {
const translation = useReasoningTranslation();
- const formatPOAction = (reasoningData?: ReasoningData) => {
+ const formatPOAction = useCallback((reasoningData?: ReasoningData) => {
if (!reasoningData) {
return {
reasoning: translation.translatePOReasonng({} as ReasoningData) || 'Purchase order required',
@@ -153,9 +154,9 @@ export function useReasoningFormatter() {
consequence,
severity
};
- };
+ }, [translation]);
- const formatBatchAction = (reasoningData?: ReasoningData) => {
+ const formatBatchAction = useCallback((reasoningData?: ReasoningData) => {
if (!reasoningData) {
return {
reasoning: translation.translateBatchReasoning({} as ReasoningData) || 'Production batch scheduled',
@@ -170,7 +171,7 @@ export function useReasoningFormatter() {
reasoning,
urgency
};
- };
+ }, [translation]);
return {
formatPOAction,