feat: optimize LongInput component with memoization and local state management
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
import { themeChange } from "theme-change";
|
import { themeChange } from "theme-change";
|
||||||
|
|
||||||
import { useRef } from "react";
|
import { useRef, useCallback } from "react";
|
||||||
import { useContext, useEffect, useState, Dispatch } from "react";
|
import { useContext, useEffect, useState, Dispatch } from "react";
|
||||||
|
import React from "react";
|
||||||
import { clearTotalCost, getTotalCost } from "@/utils/totalCost";
|
import { clearTotalCost, getTotalCost } from "@/utils/totalCost";
|
||||||
import { ChatStore, TemplateChatStore, TemplateTools } from "@/types/chatstore";
|
import { ChatStore, TemplateChatStore, TemplateTools } from "@/types/chatstore";
|
||||||
import { models } from "@/types/models";
|
import { models } from "@/types/models";
|
||||||
@@ -179,12 +180,39 @@ const SelectModel = (props: { help: string }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const LongInput = (props: {
|
const LongInput = React.memo(
|
||||||
|
(props: {
|
||||||
field: "systemMessageContent" | "toolsString";
|
field: "systemMessageContent" | "toolsString";
|
||||||
label: string;
|
label: string;
|
||||||
help: string;
|
help: string;
|
||||||
}) => {
|
}) => {
|
||||||
const { chatStore, setChatStore } = useContext(AppChatStoreContext);
|
const { chatStore, setChatStore } = useContext(AppChatStoreContext);
|
||||||
|
const textareaRef = useRef<HTMLTextAreaElement>(null);
|
||||||
|
const [localValue, setLocalValue] = useState(chatStore[props.field]);
|
||||||
|
|
||||||
|
// Update height when value changes
|
||||||
|
useEffect(() => {
|
||||||
|
if (textareaRef.current) {
|
||||||
|
autoHeight(textareaRef.current);
|
||||||
|
}
|
||||||
|
}, [localValue]);
|
||||||
|
|
||||||
|
// Sync local value with chatStore when it changes externally
|
||||||
|
useEffect(() => {
|
||||||
|
setLocalValue(chatStore[props.field]);
|
||||||
|
}, [chatStore[props.field]]);
|
||||||
|
|
||||||
|
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||||
|
setLocalValue(event.target.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBlur = () => {
|
||||||
|
if (localValue !== chatStore[props.field]) {
|
||||||
|
chatStore[props.field] = localValue;
|
||||||
|
setChatStore({ ...chatStore });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Label htmlFor="name" className="text-right">
|
<Label htmlFor="name" className="text-right">
|
||||||
@@ -205,20 +233,17 @@ const LongInput = (props: {
|
|||||||
</Label>
|
</Label>
|
||||||
|
|
||||||
<Textarea
|
<Textarea
|
||||||
|
ref={textareaRef}
|
||||||
|
mockOnChange={false}
|
||||||
className="h-24 w-full"
|
className="h-24 w-full"
|
||||||
value={chatStore[props.field]}
|
value={localValue}
|
||||||
onBlur={async (event: any) => {
|
onChange={handleChange}
|
||||||
chatStore[props.field] = event.target.value;
|
onBlur={handleBlur}
|
||||||
await setChatStore({ ...chatStore });
|
|
||||||
autoHeight(event.target);
|
|
||||||
}}
|
|
||||||
onKeyPress={(event: any) => {
|
|
||||||
autoHeight(event.target);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const InputField = (props: {
|
const InputField = (props: {
|
||||||
field:
|
field:
|
||||||
|
|||||||
Reference in New Issue
Block a user