Loading... 在开发新的渲染器核心时遇到了这个问题,着实有趣,遂提笔记录。 关于这个问题的大部分讨论都在[go-app issues #1043](https://github.com/maxence-charriere/go-app/issues/1043),也可以去[这里](https://0x.c4a1.net/usr/uploads/2025/03/3382691455.png)看截图。 --- 我遇到的问题的症结在:go-app框架在刷新组件时,会对 `(app.Compo).Render` 的返回值进行判断,用于避免重复渲染相同内容。但是它判断的依据相当粗暴,仅仅是比较新的返回值与旧返回值的类型,类型相同则忽略其内在差异,直接视为相同内容一棍子打死。 针对这个问题,[@oderwat](https://github.com/oderwat)封装 `app.UI` 并实现了一个 `replacer` ,代码在[metatexx/go-app-pkgs](https://github.com/metatexx/go-app-pkgs/blob/master/mountpoint/mountpoint.go)。实现非常简明,我就直接pin在文章里了。 ``` package mountpoint import ( "github.com/maxence-charriere/go-app/v9/pkg/app" ) type replacer interface { app.Composer nr() int set(app.UI) } type mp0 struct { app.Compo n int ui app.UI } func (c *mp0) nr() int { return c.n } func (c *mp0) set(el app.UI) { c.ui = el } func (c *mp0) Render() app.UI { return c.ui } type mp1 struct { app.Compo n int ui app.UI } func (c *mp1) nr() int { return c.n } func (c *mp1) set(el app.UI) { c.ui = el } func (c *mp1) Render() app.UI { return c.ui } type UI struct { ui replacer } // Switch lets you switch the app.UI component with another one. // It guarantees that the former component gets dismounted and // the new one gets mounted in place of the old one. func (c *UI) Switch(el app.UI) { if c.ui == el { return } if el.Mounted() { return } switch c.ui.nr() { case 0: c.ui = &mp1{ui: el, n: 1} case 1: c.ui = &mp0{ui: el} } } // UI returns the reference to the current mounted app.UI func (m *UI) UI() app.UI { return m.ui } // New creates a new mountpoint for switching app.UI components func New(ui app.UI) *UI { return &UI{&mp0{ui: ui}} } ``` 他在这里定义了 `mp1` 和 `mp2` 两种类型,均为 `replacer` 的实现。其中包含 `nr()` 和 `set()` 方法,其中 `nr()` 和 `field:n` 用于获取和记录当前的状态,而 `set()` 用于更改replacer内部的component。然后定义了 `UI` 结构体,实现了 `Switch()` 和 `UI()` 方法,用于传递当前生效的replacer。 它的工作原理是,即使原组件和新组件的类型一样,通过 `(*UI).Switch()` 和 `(*UI).UI()` 方法,总能返回一个不一样的封装,即 `mp1` 和 `mp2` 将交替作为返回值。而真正的组件被封装在它们的 `field:ui`,有了这层关系,即使 `(*mp1/*mp2).Render` 返回的是一样的类型,也将触发强制重新渲染。 --- Q.E.D. Mio 2025-03-02 06:55 提笔 2025-03-02 07:10 完稿 最后修改:2025 年 03 月 02 日 © 允许规范转载 赞 如果这对你有用,我乐意之至。
1 条评论
情感真挚自然,字里行间传递出强烈的感染力。