Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[React in Vue] Input 组件在使用双向数据绑定时的性能问题 #119

Closed
baijunjie opened this issue Apr 14, 2024 · 7 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@baijunjie
Copy link

baijunjie commented Apr 14, 2024

经过 applyPureReactInVue 转换过的 Input 组件,如果使用双向数据绑定,那么在每次输入值时,似乎都会触发整个组件的重新渲染。这会导致一个问题,就是如果在一段已经输入的文本的中间进行内容修改,只要输入一个字符,光标就会重新回到内容的尾部,让文本的修改变得非常麻烦,体验变得很差。

<script setup lang="ts">
import { ref } from "vue";
import { applyPureReactInVue } from "veaury";
import { Input } from "@nextui-org/react";

const value = ref("");

function onValueChange(val: string) {
  value.value = val;
}

const ReactInput = applyPureReactInVue(Input);
</script>

<template>
  <div>
    <ReactInput :value="value" @valueChange="onValueChange" />
  </div>
</template>

我尝试了在 React 项目中使用双向绑定时是没有这个问题的。不清楚问题是否出在 applyPureReactInVue 的内部实现中?

React DEMO
Vue最小重现 DEMO

@devilwjp
Copy link
Collaborator

@baijunjie 这个不是性能问题,是react和vue在处理input的焦点的两个微任务不在同一个事件循环中,这个缺陷后面会有语法糖或者插件去避免

@baijunjie
Copy link
Author

@baijunjie 这个不是性能问题,是react和vue在处理input的焦点的两个微任务不在同一个事件循环中,这个缺陷后面会有语法糖或者插件去避免

原来如此,期待后续的解决方案

@devilwjp devilwjp self-assigned this Apr 15, 2024
@devilwjp devilwjp added the bug Something isn't working label Apr 15, 2024
@devilwjp
Copy link
Collaborator

devilwjp commented Apr 17, 2024

@baijunjie
安装一下beta版本,veaury@beta
添加了injectSyncUpdateForPureReactInVue方法,用法如下:

import { Input } from "@nextui-org/react";
import { applyPureReactInVue, injectSyncUpdateForPureReactInVue } from 'veaury'

// 对原始的Input组件注入一次即可,之后无需再注入
injectSyncUpdateForPureReactInVue(Input, {
  // 函数名和组件状态更新的钩子函数名称要保持一致,接收到的参数也一致
  onValueChange(...args) {
    // 函数应该返回一个对象,对象的key代表了组件内容的状态值的key
    return {
      value: args[0]
    }
  }
})
const ReactInput = applyPureReactInVue(Input);

@baijunjie
Copy link
Author

@baijunjie 安装一下beta版本,veaury@beta 添加了injectSyncUpdateForPureReactInVue方法,用法如下:

import { Input } from "@nextui-org/react";
import { applyPureReactInVue, injectSyncUpdateForPureReactInVue } from 'veaury'

// 对原始的Input组件注入一次即可,之后无需再注入
injectSyncUpdateForPureReactInVue(Input, {
  // 函数名和组件状态更新的钩子函数名称要保持一致,接收到的参数也一致
  onValueChange(...args) {
    // 函数应该返回一个对象,对象的key代表了组件内容的状态值的key
    return {
      value: args[0]
    }
  }
})
const ReactInput = applyPureReactInVue(Input);

太棒了,完美解决!

@devilwjp
Copy link
Collaborator

devilwjp commented Apr 18, 2024

@baijunjie 这个问题还没有完全解决 可以合并到#120 一起解决

@devilwjp
Copy link
Collaborator

@baijunjie 再重新安装一下beta版本,2.3.17-beta.1

@baijunjie
Copy link
Author

@baijunjie 再重新安装一下beta版本,2.3.17-beta.1

升级了,看上去一切正常

devilwjp added a commit that referenced this issue Apr 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants