feat: optimize LongInput component with memoization and local state management

This commit is contained in:
ecwu
2025-01-26 21:39:23 +00:00
parent d51c283e55
commit 3b17ca791b

View File

@@ -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: