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 { useRef } from "react";
import { useRef, useCallback } from "react";
import { useContext, useEffect, useState, Dispatch } from "react";
import React from "react";
import { clearTotalCost, getTotalCost } from "@/utils/totalCost";
import { ChatStore, TemplateChatStore, TemplateTools } from "@/types/chatstore";
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";
label: string;
help: string;
}) => {
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 (
<div>
<Label htmlFor="name" className="text-right">
@@ -205,20 +233,17 @@ const LongInput = (props: {
</Label>
<Textarea
ref={textareaRef}
mockOnChange={false}
className="h-24 w-full"
value={chatStore[props.field]}
onBlur={async (event: any) => {
chatStore[props.field] = event.target.value;
await setChatStore({ ...chatStore });
autoHeight(event.target);
}}
onKeyPress={(event: any) => {
autoHeight(event.target);
}}
value={localValue}
onChange={handleChange}
onBlur={handleBlur}
/>
</div>
);
};
}
);
const InputField = (props: {
field: