TextInput 设置默认输入文本时异常触发 onChange是怎么回事?

@Entry
@Component
struct Index {
    private itemEdited: boolean = false;

    build() {
        Column() {
            TextInput({ text: '默认文本' })
                .onChange(() => {
                    this.itemEdited = true; 
                    console.log('Input changed');
                })
        }
    }

    aboutToAppear() {
        console.log('About to appear');
        this.itemEdited = false;
    }
    
    onPageShow() {
        console.log('Page appear');
        this.itemEdited = false;
    }
}

如上述代码所示,编写过程中发现如果为 TextInput 设置默认文本(而不是留空让用户输入),会触发 onChange 事件调用关联的函数。
并且这个 onChange 事件触发的位置十分奇怪,会在 aboutToAppear() 和 onPageShow() 之后触发,以至于我没办法在后两个事件中将 this.itemEdited 改回 false。

11-06 21:47:37.867 32396-12308 A0c0d0/JSAPP I About to appear
11-06 21:47:37.868 32396-12308 A0c0d0/JSAPP I Page appear
11-06 21:47:38.099 32396-12308 A0c0d0/JSAPP I Input changed
阅读 423
avatarAI BotBETA

回答

在许多框架和库中,为 TextInput 设置默认文本时触发 onChange 事件是一个已知的行为。这通常是因为内部状态更新或初始化时,框架会触发一次 onChange 以确保组件的状态与外部数据保持一致。

在你的代码中,TextInput 被初始化为包含默认文本 '默认文本',这导致 onChange 事件被触发。这个行为是框架的一部分,而不是你代码中的错误。

要解决这个问题,你可以采取以下几种策略之一:

  1. onChange 中添加条件检查
    你可以在 onChange 事件处理函数中添加一个条件检查,以确定是否是真正的用户输入导致的更改。例如,你可以比较新旧文本值,如果它们相同,则不执行任何操作。
  2. 使用其他生命周期方法或状态管理
    如果你需要在组件显示时重置某些状态,但又要避免与 TextInput 的默认文本冲突,你可以考虑使用其他生命周期方法(如 onMounted,如果可用)或在状态管理中添加额外的逻辑来处理这种情况。
  3. 延迟重置状态
    由于 onChangeaboutToAppearonPageShow 之后触发,你可以尝试使用 setTimeout 来稍微延迟重置 this.itemEdited 的操作,但这通常不是最佳实践,因为它依赖于不确定的时间间隔。

例如,你可以修改 onChange 方法来检查文本是否实际更改:

@Entry
@Component
struct Index {
    private itemEdited: boolean = false;
    private previousText: string = '默认文本';

    build() {
        Column() {
            TextInput({ text: this.previousText })
                .onChange((newValue: string) => {
                    if (newValue !== this.previousText) {
                        this.itemEdited = true;
                        this.previousText = newValue;
                        console.log('Input changed');
                    }
                })
        }
    }

    aboutToAppear() {
        console.log('About to appear');
        this.itemEdited = false;
        this.previousText = '默认文本'; // 确保重置为默认文本
    }
    
    onPageShow() {
        console.log('Page appear');
        this.itemEdited = false;
        this.previousText = '默认文本'; // 确保重置为默认文本
    }
}

在这个修改后的版本中,previousText 变量用于跟踪 TextInput 的当前值,并在 onChange 中进行比较,以避免因初始化默认文本而触发的不必要状态更改。

1 个回答

onchange,默认值也是有变化,必然会触发该事件。

然后你说的 aboutToAppear() 和 onPageShow() 先执行,这个你可以看一下生命周期,页面渲染就会执行该方法,所以在onchage前面,一点都不奇怪,当前的现象本身没有任何问题,你这种情况下应该试着修改你的代码逻辑

logo
HarmonyOS
子站问答
访问
宣传栏