SolidJS中如何通过createMemo/createEffect跟踪ref的innerHTML变化?
解决SolidJS中无法跟踪ref的innerHTML变更问题
SolidJS的createMemo和createEffect仅会对Solid自身的响应式数据源(如createSignal、createStore)的变更做出响应,原生DOM的innerHTML变化不属于Solid的响应式依赖范畴,所以你的代码里这两个API不会自动触发。
要实现跟踪contenteditable元素的内容变化,你需要通过原生DOM事件监听变更,再将内容同步到Solid的响应式信号中,让响应式系统能够感知到变化:
import { render } from "solid-js/web"; import { createSignal, createEffect, createMemo } from "solid-js"; function App() { let divRef; // 创建响应式信号存储内容 const [content, setContent] = createSignal("this is editable content"); // 监听contenteditable的输入事件,同步内容到信号 const handleInput = () => { if (divRef) { setContent(divRef.innerHTML); } }; // 现在依赖响应式信号,就能跟踪内容变化了 const memo = createMemo(() => { console.log("this is memo: ", content()); return content(); }); createEffect(() => { console.log("this is effect: ", content()); }); return ( <div contenteditable={true} ref={divRef} onInput={handleInput} innerHTML={content()} /> ); } render(() => <App />, document.getElementById("app"));
关键说明:
- 使用
onInput事件监听contenteditable元素的实时内容变更,这是原生DOM支持的事件,能覆盖输入、粘贴等所有内容修改场景 - 将DOM内容同步到
content信号后,createMemo和createEffect因为依赖了content()这个响应式值,会在内容变化时自动触发 - 也可以直接在
handleInput回调中执行控制台打印逻辑,但通过响应式信号管理内容,更符合SolidJS的响应式设计范式,方便后续在多个地方复用内容
内容的提问来源于stack exchange,提问作者Victor Zhuravlev
相关产品推荐
相关产品推荐

