Skip to content

Conversation

@SocietyNiu
Copy link

@SocietyNiu SocietyNiu commented Nov 4, 2025

This PR addresses issue #77 .
The same solution as react-component/input#61.
test

Summary by CodeRabbit

Bug Fixes

  • 改进了文本框对输入法(IME)输入事件的处理机制。系统现已能够准确识别不同的输入事件来源,防止在输入法组合转换过程中发生意外的状态更新,显著增强了中文、日文等多语言输入场景下的稳定性和用户体验。

@coderabbitai
Copy link

coderabbitai bot commented Nov 4, 2025

Walkthrough

在 src/TextArea.tsx 中为 triggerChange 方法添加了 ChangeEventInfo 参数以区分事件源,并在组合事件结束时添加了条件守卫以防止意外的状态变化。同时在 src/interface.ts 中新增导出接口 ChangeEventInfo。

Changes

聚合类 / 文件 改动摘要
新增类型定义
src/interface.ts
新增导出接口 ChangeEventInfo,包含 source 字段,用于标识变化事件的来源('compositionEnd' | 'change')
核心逻辑改动
src/TextArea.tsx
扩展 triggerChange 方法签名以接受 info: ChangeEventInfo 参数;在三个调用点传播 info 对象;在 compositionEnd 流程中添加守卫条件,当 info.source === 'compositionEnd' 时跳过值更新;调整导入顺序

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant TextArea as TextArea Component
    participant triggerChange as triggerChange
    participant onChange as onChange Handler

    User->>TextArea: Composition End Event
    TextArea->>triggerChange: Call with info.source='compositionEnd'
    alt source === 'compositionEnd'
        triggerChange->>triggerChange: Skip value update (guard)
    end
    triggerChange->>onChange: Emit change event
    
    User->>TextArea: Regular Change Event
    TextArea->>triggerChange: Call with info.source='change'
    triggerChange->>triggerChange: Process value update
    triggerChange->>onChange: Emit change event
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 分钟

  • 需要验证 triggerChange 的三个调用点是否都正确传递了 info 参数
  • 确认 compositionEnd 的守卫条件逻辑是否完整解决组合事件重复触发问题
  • 检查 ChangeEventInfo 接口的类型约束是否完整且与实际使用场景匹配

Possibly related issues

Poem

🐰 小兔蹦跳来修复,
compositionEnd 不再双声鸣;
info 信使来传话,
事件源头清晰分,
文本框稳稳当当~

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately describes the main change: triggering onChange twice when using IME input. This directly relates to the core functionality added in the changeset, which involves tracking the source of change events (compositionEnd vs change) and handling them appropriately.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 17f20cd and ad93681.

📒 Files selected for processing (2)
  • src/TextArea.tsx (4 hunks)
  • src/interface.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/TextArea.tsx (1)
src/interface.ts (1)
  • ChangeEventInfo (48-50)
🔇 Additional comments (5)
src/interface.ts (1)

47-50: 新增的 ChangeEventInfo 接口定义合理!

接口清晰地定义了事件源的类型约束,用于区分 IME 输入的不同阶段,这是解决双重触发问题的关键。

src/TextArea.tsx (4)

10-10: 导入变更正确!

正确引入了 ChangeEventInfo 类型用于区分事件源。

Also applies to: 15-15


104-110: 函数签名扩展合理!

triggerChange 添加 info 参数使函数能够根据事件源执行不同的逻辑,这是实现修复的核心改动。


149-149: 调用点更新完整!

两个调用点都正确传递了 info 参数:

  • compositionEnd 时传递 { source: 'compositionEnd' }
  • change 事件时传递 { source: 'change' }

参数传递准确且一致。

Also applies to: 154-154


129-131: 补充测试:验证 IME 输入时 onChange 调用计数

固卫条件逻辑正确,但现有测试缺少关键验证。当前测试只验证最终值是否正确截断,未验证 onChange 调用次数的去重。

建议补充测试用例,在 tests/index.spec.tsx 中添加:

  • 验证 IME 输入超过 maxLength 时,onChange 仅被调用一次(不是两次)
  • 验证正常非 IME 输入不受影响,onChange 仍正常触发

当前已有的功能测试(exceedFormatter 值截断正确)不足以证明去重逻辑生效。


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @SocietyNiu, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves a bug where the onChange event was being triggered twice when using IME input in the TextArea component. The fix involves distinguishing between compositionEnd and regular change events to prevent duplicate triggers, ensuring that the onChange event is only fired once per actual change.

Highlights

  • Issue Fix: This PR addresses issue Input onChange trigger two times when input Chinese #77, which involves the onChange event being triggered twice when using IME input in the TextArea component.
  • Solution: The solution implemented is the same as the one used in fix: trigger onChange twice when inputting using the input method input#61, which likely involves handling the compositionEnd event to prevent duplicate onChange triggers.
  • Code Changes: The changes include adding a source field to the ChangeEventInfo interface to differentiate between compositionEnd and regular change events. The triggerChange function is updated to include this source information, and the onCompositionEnd handler is modified to trigger change with compositionEnd source.
  • Event Handling: The onInternalChange handler now also includes the source information as change.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request aims to fix an issue where onChange is triggered twice when using an IME by introducing a source to the change event. While the approach is sound, the current implementation has a logical flaw. The fix works correctly when maxLength is not a factor, but it fails to prevent the double trigger when maxLength is active and exceeded, as the new logic is bypassed. I've provided a suggestion to correct this logic to ensure onChange is only fired once in all scenarios.

@SocietyNiu
Copy link
Author

Code Review

This pull request aims to fix an issue where onChange is triggered twice when using an IME by introducing a source to the change event. While the approach is sound, the current implementation has a logical flaw. The fix works correctly when maxLength is not a factor, but it fails to prevent the double trigger when maxLength is active and exceeded, as the new logic is bypassed. I've provided a suggestion to correct this logic to ensure onChange is only fired once in all scenarios.

The expected result is for OnChange to be triggered twice when the input exceeds the maxLength. As the image shows, the whole string will be outputted the first time and the second time there will be a cut string. The implementation within rl-input is the same. Users should manage the difference.
test2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant