• prosemirror error - Applying a mismatched transaction


    bug描述

    使用 prosemirror 时,dispatch transcation 报错:
    在这里插入图片描述
    代码如下(简化版):

    import { inject } from "vue";
    const editorView = inject("editorView");
    
    function handleClick() {
      const view = editorView.value;
      view.dispatch(view.state.tr.deleteSelection());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在 prosemirror discuss 找到了相关问题:RangeError: Applying a mismatched transaction。pm 的作者在讨论中解释了这个 error 的含义:

    “Mismatched transaction” errors mean that something is trying to dispatch a transaction that doesn’t start from the view’s current state—I.e. if you create the transaction but then don’t synchronously dispatch it, it’d be possible for another transaction to happen in the meantime, which makes your transaction invalid. The rest of the stack trace for the error likely points at the code that’s dispatching the transaction on the outdated (or, possibly, completely unrelated) state.

    很奇怪,我没有用异步操作啊。顺着报错stack,找到 applyInner 方法。发现当 eq() 返回 false时,会抛出 error

    在这里插入图片描述
    查看 eq 方法,根据注释知道它是用来判断 thisother 是否代表同一块内容。
    在这里插入图片描述
    查看 this,是 Vue的 Reactive 对象,包着 doc Node。
    在这里插入图片描述

    查看 other:是 doc Node 对象
    在这里插入图片描述

    破案了。

    解释

    我项目用的 vue3。在父组件中把 editorView 用 ref 包了一下,然后 provide 下去。

    const editorView = ref()
    provide("editorView", editorView );
    onMounted(() => {
      editorView.value = new EditorView();
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5

    子组件(也就是调用 dispatch 的组件) inject 进来的是这个 ref 对象。
    在 vue 3 中被 ref 包着的对象,通过.value 得到的不是原对象,而是原对象的 proxy!

    解决方法:在 vue3 项目中不要用 ref 了,用 shallowRef

    const editorView = shallowRef()
    
    • 1

    测试 vue2 和 vue3

    const obj ={a:1}
    console.log(obj === ref(obj).value)
    
    • 1
    • 2

    同样一段代码,在 vue2 环境中是 true,在 vue3 中是 false
    平时工作项目里一直用 vue2,这次测试项目装的 vue3,没注意差别
    一定要记得,vue2 和 vue3 的响应式原理是有区别的。平时开发不显眼,一旦踩坑就很麻烦

  • 相关阅读:
    spring boot社区居民健康档案管理系统毕业设计源码220940
    NFS:使用 Ansible 自动化配置 NFS 客户端服务端
    <蓝桥杯软件赛>零基础备赛20周--第2周
    微服务自动化【Docker-Compose】
    防范与解决.faust勒索病毒:恢复数据文件与预防方法
    JS 通过年份获取月,季度,半年度,年度
    Java-Redis-Redisson-分布式锁(万能)
    系列七、Redis持久化
    第1章丨IRIS Globals 简介
    TPCH_Q4 的分析优化,对子查询中的 Semi-join 优化
  • 原文地址:https://blog.csdn.net/tangran0526/article/details/133795149