From 1b1b9a2874aea63fd2436d0e8d55b413952c4d1e Mon Sep 17 00:00:00 2001 From: deep1401 <gandhi0869@gmail.com> Date: Wed, 26 Feb 2025 10:06:52 -0800 Subject: [PATCH] UseMemo to eliminate the usage of useEffect and correct minor bug which happens when setting some tasks in AutoComplete --- .../Experiment/DynamicPluginForm.tsx | 8 ++- .../Widgets/CustomEvaluationWidget.tsx | 72 +++++++------------ 2 files changed, 33 insertions(+), 47 deletions(-) diff --git a/src/renderer/components/Experiment/DynamicPluginForm.tsx b/src/renderer/components/Experiment/DynamicPluginForm.tsx index 81adccf3..a2455bad 100644 --- a/src/renderer/components/Experiment/DynamicPluginForm.tsx +++ b/src/renderer/components/Experiment/DynamicPluginForm.tsx @@ -422,7 +422,13 @@ function CustomAutocompleteWidget<T = any, S extends StrictRJSFSchema = RJSFSche // Determine default value. const defaultValue = _multiple ? [] : ''; // Use the provided value or fallback to default. - const currentValue = value !== undefined ? value : defaultValue; + let currentValue = value !== undefined ? value : defaultValue; + + // Check if currentValue is an array, if a string, convert it to an array. + const isString = typeof currentValue === 'string'; + if (isString) { + currentValue = currentValue.split(','); + } // Map enumOptions into objects with label and value. const processedOptionsValues = enumOptions.map((opt) => diff --git a/src/renderer/components/Experiment/Widgets/CustomEvaluationWidget.tsx b/src/renderer/components/Experiment/Widgets/CustomEvaluationWidget.tsx index 6adac389..2ffc64ca 100644 --- a/src/renderer/components/Experiment/Widgets/CustomEvaluationWidget.tsx +++ b/src/renderer/components/Experiment/Widgets/CustomEvaluationWidget.tsx @@ -1,12 +1,6 @@ import React from 'react'; import { WidgetProps } from '@rjsf/core'; -import { - Button, - Input, - Select, - Option, -} from '@mui/joy'; - +import { Button, Input, Select, Option } from '@mui/joy'; type EvaluationField = { name: string; @@ -14,55 +8,44 @@ type EvaluationField = { return_type: string; }; - -const CustomEvaluationWidget = (props: WidgetProps<any>) => { - const { id, value, onChange, disabled, readonly } = props; - - - const parseValue = (val: any): EvaluationField[] => { - if (Array.isArray(val)) { - if (val.every(item => typeof item === "string")) { - // If every element is a string: join them and parse the result. - try { - const joined = val.join(','); - const parsed = JSON.parse(joined); - return Array.isArray(parsed) ? parsed : []; - } catch (err) { - console.error("Error parsing evaluation widget value:", err); - return []; - } - } else { - // If not all elements are strings, assume it's already an array of EvaluationField. - return val; - } - } else if (typeof val === "string") { +const parseValue = (val: any): EvaluationField[] => { + if (Array.isArray(val)) { + if (val.every(item => typeof item === "string")) { + // If every element is a string: join them and parse the result. try { - return JSON.parse(val); + const joined = val.join(','); + const parsed = JSON.parse(joined); + return Array.isArray(parsed) ? parsed : []; } catch (err) { - console.error("Error parsing evaluation widget value string:", err); + console.error("Error parsing evaluation widget value:", err); return []; } + } else { + // If not all elements are strings, assume it's already an array of EvaluationField. + return val; } - return []; - }; - - const [evalMetrics, setEvalMetrics] = React.useState<EvaluationField[]>(parseValue(value)); + } else if (typeof val === "string") { + try { + return JSON.parse(val); + } catch (err) { + console.error("Error parsing evaluation widget value string:", err); + return []; + } + } + return []; +}; +const CustomEvaluationWidget = (props: WidgetProps<any>) => { + const { id, value, onChange, disabled, readonly } = props; - // Update state if a new default value is provided - React.useEffect(() => { - const parsed = parseValue(value); - if (JSON.stringify(parsed) !== JSON.stringify(evalMetrics) && parsed.length > 0) { - setEvalMetrics(parsed); - } - }, [value]); + // Directly derive evaluation metrics from the value prop. + const evalMetrics: EvaluationField[] = React.useMemo(() => parseValue(value), [value]); const handleAddField = () => { const updatedMetrics = [ ...evalMetrics, { name: '', expression: '', return_type: 'boolean' } ]; - setEvalMetrics(updatedMetrics); onChange(updatedMetrics); }; @@ -74,13 +57,11 @@ const CustomEvaluationWidget = (props: WidgetProps<any>) => { const updated = evalMetrics.map((evaluation, i) => i === index ? { ...evaluation, [field]: newValue } : evaluation ); - setEvalMetrics(updated); onChange(updated); }; const handleRemoveField = (index: number) => { const updated = evalMetrics.filter((_, i) => i !== index); - setEvalMetrics(updated); onChange(updated); }; @@ -126,7 +107,6 @@ const CustomEvaluationWidget = (props: WidgetProps<any>) => { <Option value="number">Number</Option> <Option value="contains">Contains</Option> <Option value="isequal">IsEqual</Option> - </Select> <Button onClick={() => handleRemoveField(index)} -- GitLab