0.1.39 P1: MemberCard memo 化 + FamilyPanel useMemo 排序缓存(脱离 store 订阅)

This commit is contained in:
2026-09-13 13:04:10 +08:00
parent fdc9d750f2
commit 818c6025f4
2 changed files with 47 additions and 34 deletions
+27 -19
View File
@@ -1,4 +1,4 @@
import { useGameStore } from '../store'
import { memo } from 'react'
import { Character } from '../../game/types/domain'
import { describeRealm } from '../../game/data/realms'
import { describeRoots } from '../../game/data/elements'
@@ -13,18 +13,34 @@ const STATE_LABEL: Record<string, { label: string; cls: string }> = {
dead: { label: '已殁', cls: 'bad' }
}
export function MemberCard({ c }: { c: Character }) {
const world = useGameStore((s) => s.world)
const setSelected = useGameStore((s) => s.setSelected)
if (!world) return null
const C_STATE: Record<string, string> = {
idle: '',
meditation: 'good',
expedition: 'warn',
wounded: 'bad',
dead: 'bad'
}
/**
* 0.1.39 渲染提效:MemberCard 改为 memo 纯展示组件——
* 不再从 store 获取 world(之前每次 revision bump 全部卡片重渲染)。
* 所需外部数据(surname/isHead/age)经 props 传入,只在 c 或依赖 props 变化时重渲染。
*/
export interface MemberCardProps {
c: Character
surname: string
isHead: boolean
age: number
onSelect: (id: string) => void
}
export const MemberCard = memo(function MemberCard({ c, surname, isHead, age, onSelect }: MemberCardProps) {
const dead = !c.alive
const isHead = world.state.family.headId === c.id
const state = STATE_LABEL[dead ? 'dead' : c.state]
const blocked = !dead && c.realmProgress >= 100 && c.realm.major !== 'spirit'
return (
<div className={`member-card ${dead ? 'dead' : ''} ${blocked ? 'blocked' : ''}`} onClick={() => setSelected(c.id)}>
<div className={`member-card ${dead ? 'dead' : ''} ${blocked ? 'blocked' : ''}`} onClick={() => onSelect(c.id)}>
<div className="mc-head">
<div className="m-avatar">{world.state.family.surname}</div>
<div className="m-avatar">{surname}</div>
<div style={{ flex: 1 }}>
<div className="member-name">
<span>{c.name}</span>
@@ -34,7 +50,7 @@ export function MemberCard({ c }: { c: Character }) {
<div className="member-realm">
{dead
? `殁于${c.deathYear}年 · ${c.deathCause ?? '寿终'}`
: `${describeRealm(c.realm)} · ${world.ageOf(c)}岁 · 修为${Math.floor(c.realmProgress)}%`}
: `${describeRealm(c.realm)} · ${age}岁 · 修为${Math.floor(c.realmProgress)}%`}
</div>
</div>
</div>
@@ -55,12 +71,4 @@ export function MemberCard({ c }: { c: Character }) {
)}
</div>
)
}
const C_STATE: Record<string, string> = {
idle: '',
meditation: 'good',
expedition: 'warn',
wounded: 'bad',
dead: 'bad'
}
})