🐛fix: Fix React hooks order violation causing page crash on API errors

- Move useEffect hooks before conditional returns in MessageContent and ThinkingContent
- Ensure hooks are called in the same order every render
- Fix "Rendered fewer hooks than expected" error when API returns non-200 status
- Follow React hooks rules: only call hooks at the top level

This prevents the entire page from crashing when API requests fail.
This commit is contained in:
Apple\Apple
2025-06-02 21:26:56 +08:00
parent 07ffc36678
commit f9c8a802ef
2 changed files with 12 additions and 15 deletions

View File

@@ -28,6 +28,15 @@ const MessageContent = ({
const previousContentLengthRef = useRef(0);
const lastContentRef = useRef('');
const isThinkingStatus = message.status === 'loading' || message.status === 'incomplete';
useEffect(() => {
if (!isThinkingStatus) {
previousContentLengthRef.current = 0;
lastContentRef.current = '';
}
}, [isThinkingStatus]);
if (message.status === 'error') {
let errorText;
@@ -51,7 +60,6 @@ const MessageContent = ({
);
}
const isThinkingStatus = message.status === 'loading' || message.status === 'incomplete';
let currentExtractedThinkingContent = null;
let currentDisplayableFinalContent = "";
let thinkingSource = null;
@@ -130,14 +138,6 @@ const MessageContent = ({
const finalExtractedThinkingContent = currentExtractedThinkingContent;
const finalDisplayableFinalContent = currentDisplayableFinalContent;
// 流式状态结束时重置
useEffect(() => {
if (!isThinkingStatus) {
previousContentLengthRef.current = 0;
lastContentRef.current = '';
}
}, [isThinkingStatus]);
if (message.role === 'assistant' &&
isThinkingStatus &&
!finalExtractedThinkingContent &&

View File

@@ -15,25 +15,23 @@ const ThinkingContent = ({
const scrollRef = useRef(null);
const lastContentRef = useRef('');
if (!finalExtractedThinkingContent) return null;
const isThinkingStatus = message.status === 'loading' || message.status === 'incomplete';
const headerText = (isThinkingStatus && !message.isThinkingComplete) ? t('思考中...') : t('思考过程');
useEffect(() => {
if (scrollRef.current) {
if (scrollRef.current && finalExtractedThinkingContent && message.isReasoningExpanded) {
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
}
}, [finalExtractedThinkingContent, message.isReasoningExpanded]);
// 流式状态结束时重置
useEffect(() => {
if (!isThinkingStatus) {
lastContentRef.current = '';
}
}, [isThinkingStatus]);
// 获取上一次的内容长度
if (!finalExtractedThinkingContent) return null;
let prevLength = 0;
if (isThinkingStatus && lastContentRef.current) {
if (finalExtractedThinkingContent.startsWith(lastContentRef.current)) {
@@ -41,7 +39,6 @@ const ThinkingContent = ({
}
}
// 更新最后内容的引用
if (isThinkingStatus) {
lastContentRef.current = finalExtractedThinkingContent;
}