You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

状态更新时update函数打印DOM元素返回undefined问题排查

问题原因与解决方案:on-change回调中this.el为undefined

核心原因:this指向丢失

当你把this.update作为回调传给onChange函数时,只是传递了函数本身,没有绑定它的上下文(this的指向)。在严格模式下,on-change库内部调用这个回调时,this会默认变成undefined,所以update里访问this.el拿不到实例上的DOM元素。

而直接调用app.update()时,this会自动绑定到app这个App类的实例对象上,因此能正常打印this.el。

另外提一句:你代码里的this.state.count = this.state.count += 1;是冗余写法,直接写this.state.count += 1就可以实现count加1的效果。

三种解决方案

1. 在构造函数中绑定this

通过bind方法把update函数的this强制绑定到App实例上,再传给onChange:

import onChange from 'on-change';
import './style.css';

class App {
    constructor() {
        const state = {
            count: 0,
        }
        // 绑定update的this到当前实例
        this.update = this.update.bind(this);
        this.state = onChange(state, this.update);

        this.el = document.createElement('div');
        this.btn = document.createElement('button');
        this.btn.textContent = "Click Me!";
        this.btn.addEventListener("click", e => {
            this.state.count += 1;
        })
        this.el.appendChild(this.btn);
        this.el.className = 'container';
    }

    update(path, current, previous) {
        console.log(this.el); // 正常打印div元素
    }
}

const app = new App();
app.update();
document.body.appendChild(app.el);

2. 使用箭头函数作为on-change的回调

箭头函数会继承外层作用域的this(也就是App实例),把回调包装成箭头函数即可:

// 构造函数里修改这一行
this.state = onChange(state, (path, current, previous) => this.update(path, current, previous));

3. 将update方法定义为箭头函数

在类中直接用箭头函数定义update,它的this会永久绑定到App实例:

class App {
    constructor() {
        const state = {
            count: 0,
        }
        this.state = onChange(state, this.update);

        this.el = document.createElement('div');
        this.btn = document.createElement('button');
        this.btn.textContent = "Click Me!";
        this.btn.addEventListener("click", e => {
            this.state.count += 1;
        })
        this.el.appendChild(this.btn);
        this.el.className = 'container';
    }

    // 用箭头函数定义update
    update = (path, current, previous) => {
        console.log(this.el); // 正常打印div元素
    }
}

const app = new App();
app.update();
document.body.appendChild(app.el);

内容的提问来源于stack exchange,提问作者ullieiseenstupidhond12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 23:26:05