refactor(ThinkingEffect): replace useState+useEffect with useMemo (#12536)

refactor(ThinkingEffect): replace useState+useEffect with useMemo for derived state

The messages array is purely derived from content and isThinking props,
not fetched from an API. Using useState+useEffect for derived state is
a React anti-pattern that causes unnecessary re-renders.

This change:
- Removes lodash isEqual dependency
- Reduces code complexity
- Avoids double render cycle

Signed-off-by: SherlockShemol <shemol@163.com>
This commit is contained in:
Shemol 2026-01-21 14:53:45 +08:00 committed by GitHub
parent bd4f4db572
commit ed54bf8810
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,8 +1,7 @@
import { lightbulbVariants } from '@renderer/utils/motionVariants'
import { isEqual } from 'lodash'
import { ChevronRight, Lightbulb } from 'lucide-react'
import { motion } from 'motion/react'
import React, { useEffect, useMemo, useState } from 'react'
import React, { useMemo } from 'react'
import styled from 'styled-components'
interface Props {
@ -13,17 +12,11 @@ interface Props {
}
const ThinkingEffect: React.FC<Props> = ({ isThinking, thinkingTimeText, content, expanded }) => {
const [messages, setMessages] = useState<string[]>([])
useEffect(() => {
const messages = useMemo(() => {
const allLines = (content || '').split('\n')
const newMessages = isThinking ? allLines.slice(0, -1) : allLines
const validMessages = newMessages.filter((line) => line.trim() !== '')
if (!isEqual(messages, validMessages)) {
setMessages(validMessages)
}
}, [content, isThinking, messages])
return newMessages.filter((line) => line.trim() !== '')
}, [content, isThinking])
const showThinking = useMemo(() => {
return isThinking && !expanded