🐛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:
@@ -28,6 +28,15 @@ const MessageContent = ({
|
|||||||
const previousContentLengthRef = useRef(0);
|
const previousContentLengthRef = useRef(0);
|
||||||
const lastContentRef = useRef('');
|
const lastContentRef = useRef('');
|
||||||
|
|
||||||
|
const isThinkingStatus = message.status === 'loading' || message.status === 'incomplete';
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isThinkingStatus) {
|
||||||
|
previousContentLengthRef.current = 0;
|
||||||
|
lastContentRef.current = '';
|
||||||
|
}
|
||||||
|
}, [isThinkingStatus]);
|
||||||
|
|
||||||
if (message.status === 'error') {
|
if (message.status === 'error') {
|
||||||
let errorText;
|
let errorText;
|
||||||
|
|
||||||
@@ -51,7 +60,6 @@ const MessageContent = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const isThinkingStatus = message.status === 'loading' || message.status === 'incomplete';
|
|
||||||
let currentExtractedThinkingContent = null;
|
let currentExtractedThinkingContent = null;
|
||||||
let currentDisplayableFinalContent = "";
|
let currentDisplayableFinalContent = "";
|
||||||
let thinkingSource = null;
|
let thinkingSource = null;
|
||||||
@@ -130,14 +138,6 @@ const MessageContent = ({
|
|||||||
const finalExtractedThinkingContent = currentExtractedThinkingContent;
|
const finalExtractedThinkingContent = currentExtractedThinkingContent;
|
||||||
const finalDisplayableFinalContent = currentDisplayableFinalContent;
|
const finalDisplayableFinalContent = currentDisplayableFinalContent;
|
||||||
|
|
||||||
// 流式状态结束时重置
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isThinkingStatus) {
|
|
||||||
previousContentLengthRef.current = 0;
|
|
||||||
lastContentRef.current = '';
|
|
||||||
}
|
|
||||||
}, [isThinkingStatus]);
|
|
||||||
|
|
||||||
if (message.role === 'assistant' &&
|
if (message.role === 'assistant' &&
|
||||||
isThinkingStatus &&
|
isThinkingStatus &&
|
||||||
!finalExtractedThinkingContent &&
|
!finalExtractedThinkingContent &&
|
||||||
|
|||||||
@@ -15,25 +15,23 @@ const ThinkingContent = ({
|
|||||||
const scrollRef = useRef(null);
|
const scrollRef = useRef(null);
|
||||||
const lastContentRef = useRef('');
|
const lastContentRef = useRef('');
|
||||||
|
|
||||||
if (!finalExtractedThinkingContent) return null;
|
|
||||||
|
|
||||||
const isThinkingStatus = message.status === 'loading' || message.status === 'incomplete';
|
const isThinkingStatus = message.status === 'loading' || message.status === 'incomplete';
|
||||||
const headerText = (isThinkingStatus && !message.isThinkingComplete) ? t('思考中...') : t('思考过程');
|
const headerText = (isThinkingStatus && !message.isThinkingComplete) ? t('思考中...') : t('思考过程');
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (scrollRef.current) {
|
if (scrollRef.current && finalExtractedThinkingContent && message.isReasoningExpanded) {
|
||||||
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
||||||
}
|
}
|
||||||
}, [finalExtractedThinkingContent, message.isReasoningExpanded]);
|
}, [finalExtractedThinkingContent, message.isReasoningExpanded]);
|
||||||
|
|
||||||
// 流式状态结束时重置
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!isThinkingStatus) {
|
if (!isThinkingStatus) {
|
||||||
lastContentRef.current = '';
|
lastContentRef.current = '';
|
||||||
}
|
}
|
||||||
}, [isThinkingStatus]);
|
}, [isThinkingStatus]);
|
||||||
|
|
||||||
// 获取上一次的内容长度
|
if (!finalExtractedThinkingContent) return null;
|
||||||
|
|
||||||
let prevLength = 0;
|
let prevLength = 0;
|
||||||
if (isThinkingStatus && lastContentRef.current) {
|
if (isThinkingStatus && lastContentRef.current) {
|
||||||
if (finalExtractedThinkingContent.startsWith(lastContentRef.current)) {
|
if (finalExtractedThinkingContent.startsWith(lastContentRef.current)) {
|
||||||
@@ -41,7 +39,6 @@ const ThinkingContent = ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新最后内容的引用
|
|
||||||
if (isThinkingStatus) {
|
if (isThinkingStatus) {
|
||||||
lastContentRef.current = finalExtractedThinkingContent;
|
lastContentRef.current = finalExtractedThinkingContent;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user