fix(post): 上下篇切换后正文内容不更新
承接 fix(post) 的路由重跑修复:标题/描述更新后,正文仍停留在旧文章。 根因:PostContent 用 use_memo 缓存 split_content_fragments 的结果,但 memo 依赖 ReactiveContext 追踪闭包内读取的 signal 才会重算。content_html 是普通 String prop,读取它不建立订阅——memo 永久缓存首次解析结果。上下篇切换时 content_html prop 已是新文章的 HTML,但 memo 返回旧 fragments,dangerous_inner_html 收到旧 html 字符串,diff 判断属性值未变 → 不生成 setAttribute 编辑 → 正文 DOM 停在旧文章。 标题/描述之所以正常更新:它们直接读 post(来自 use_server_future 的 Resource, 是 signal),不走 memo。 修复:去掉 use_memo,直接在 render 内调用 split_content_fragments(纯函数, 符合渲染纯净性)。每次渲染用当前 content_html 重新解析,diff 收到新 html → 正文 DOM 正确更新。 验证(headless chromium): - 修复前:/post/rust 点 Next,标题变「写文章页面改为左右布局」,正文仍是 rust 的「第一步:定义世界」(红灯,复现) - 修复后:正文随之变为「问题」(绿灯);prev 方向同样通过;首次 SSR 正常
This commit is contained in:
parent
1c56fd8ec1
commit
f86cb48efe
@ -126,9 +126,15 @@ fn invoke_optional_global(window: &web_sys::Window, name: &str, args: &[wasm_bin
|
|||||||
/// 这里仅设置其初始化配置 `__lightboxSelectors` 并兜底调用。
|
/// 这里仅设置其初始化配置 `__lightboxSelectors` 并兜底调用。
|
||||||
#[component]
|
#[component]
|
||||||
pub fn PostContent(content_html: String) -> Element {
|
pub fn PostContent(content_html: String) -> Element {
|
||||||
// 拆分片段:use_memo 避免每次渲染重复解析。
|
// 直接在 render 内拆分片段(纯函数调用,符合渲染纯净性)。
|
||||||
let fragments =
|
//
|
||||||
use_memo(move || split_content_fragments(&content_html));
|
// 不用 use_memo:memo 依赖 ReactiveContext 追踪闭包内读取的 signal 才会重算,
|
||||||
|
// 但 content_html 是普通 String prop,读取它不建立订阅——memo 会永久缓存首次
|
||||||
|
// 解析结果。当上下篇切换、content_html prop 变化时 memo 不重算,返回旧 fragments,
|
||||||
|
// 导致 dangerous_inner_html 收到旧 html、diff 判断属性未变 → 正文 DOM 不更新
|
||||||
|
// (表现为标题/描述更新了但正文停在旧文章)。split_content_fragments 是纯函数,
|
||||||
|
// 每次渲染重新解析开销可控。
|
||||||
|
let fragments = split_content_fragments(&content_html);
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use_effect(move || {
|
use_effect(move || {
|
||||||
@ -151,7 +157,7 @@ pub fn PostContent(content_html: String) -> Element {
|
|||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
div { class: "post-content md-content",
|
div { class: "post-content md-content",
|
||||||
for (i, fragment) in fragments.read().iter().enumerate() {
|
for (i, fragment) in fragments.iter().enumerate() {
|
||||||
{match fragment {
|
{match fragment {
|
||||||
ContentFragment::Html(html) => rsx! {
|
ContentFragment::Html(html) => rsx! {
|
||||||
div { key: "html-{i}", dangerous_inner_html: "{html}" }
|
div { key: "html-{i}", dangerous_inner_html: "{html}" }
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user