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

fix(inputnumber): 增加 beforeChange,优化异步逻辑 #2950

Open
wants to merge 2 commits into
base: next
Choose a base branch
from

Conversation

oasis-cloud
Copy link
Collaborator

@oasis-cloud oasis-cloud commented Jan 17, 2025

🤔 这个变动的性质是?

  • 新特性提交
  • 日常 bug 修复

🔗 相关 Issue

#2530

💡 需求背景和解决方案

async 属性和 onChange 的组合实现的用法不明确,实际场景中主要在 onChange 之前检查是不是可以更改 Input 中的值。基于这样的情况,增加了 beforeChange 方法。

Summary by CodeRabbit

  • 新功能

    • 为 InputNumber 组件引入了 beforeChange 属性,允许在输入值变更前进行异步验证
    • 扩展了 InputNumber 组件的输入值范围,最小值从 -6 调整到 -9999
  • 文档更新

    • 更新了 InputNumber 组件的文档,添加了版本信息和新属性说明
    • 移除了 async 属性,并引入了更灵活的 beforeChange 属性
  • 性能优化

    • 新增防抖功能,控制输入变更的执行延迟
    • 改进了输入值变更的控制流程,提供更精细的输入验证机制
  • 测试改进

    • 更新了测试用例以支持异步事件处理,确保状态更新的准确性

Copy link

coderabbitai bot commented Jan 17, 2025

概述

演练

这个拉取请求主要修改了 InputNumber 组件的行为和文档。引入了一个新的 beforeChange 属性,替换了原有的 async 属性,提供了更灵活的输入值变更控制机制。同时,在演示文件中添加了 useDebounce 自定义钩子,用于延迟函数执行。文档也相应地更新了组件属性的描述和版本信息。

变更

文件 变更摘要
src/packages/inputnumber/demos/h5/demo8.tsx
src/packages/inputnumber/demos/taro/demo8.tsx
添加 useDebounce 自定义钩子,修改 onChange 处理逻辑,更新 min 属性范围
src/packages/inputnumber/doc*.md 更新文档,添加 beforeChange 属性,移除 async 属性,添加版本信息
src/packages/inputnumber/inputnumber.tsx
src/packages/inputnumber/inputnumber.taro.tsx
移除 async 属性,添加 beforeChange 属性,修改值更新逻辑
src/packages/inputnumber/__tests__/inputnumber.spec.tsx 更新测试用例,添加异步处理以确保事件正确处理

可能相关的 PR

建议标签

size/M

建议审阅者

  • xiaoyatong
  • irisSong

诗歌

🐰 输入数字,轻轻慢慢
防抖钩子,控制自如
属性变换,代码飞扬
输入之前,先来把关
优雅敏捷,兔子欢唱!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

codecov bot commented Jan 17, 2025

Codecov Report

Attention: Patch coverage is 98.03922% with 1 line in your changes missing coverage. Please review.

Project coverage is 84.14%. Comparing base (16fb6e5) to head (c91aa96).

Files with missing lines Patch % Lines
src/packages/inputnumber/inputnumber.tsx 98.03% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             next    #2950      +/-   ##
==========================================
+ Coverage   84.03%   84.14%   +0.10%     
==========================================
  Files         220      220              
  Lines       17917    17884      -33     
  Branches     2628     2624       -4     
==========================================
- Hits        15057    15048       -9     
+ Misses       2855     2831      -24     
  Partials        5        5              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
src/packages/inputnumber/demos/taro/demo8.tsx (2)

4-19: 建议优化 useDebounce 钩子的类型安全性和清理逻辑

建议进行以下改进:

-  const timeoutId: any = useRef()
+  const timeoutId = useRef<NodeJS.Timeout>()

   const cleanup = useCallback(() => {
     if (timeoutId.current) {
       clearTimeout(timeoutId.current)
     }
   }, [])

+  useEffect(() => {
+    return cleanup
+  }, [cleanup])

   return function (...args: T) {
-    if (timeoutId.current) {
-      clearTimeout(timeoutId.current)
-    }
+    cleanup()
     timeoutId.current = setTimeout(() => {
       func(...args)
     }, delay)
   }

35-41: 建议优化异步演示的实现方式

当前实现使用了硬编码的延迟时间和中文提示信息,建议:

  1. 将延迟时间抽取为可配置的常量
  2. 使用国际化文本支持多语言
+const DEBOUNCE_DELAY = 300
+const ASYNC_DELAY = 2000
+const messages = {
+  'zh-CN': '异步演示 2 秒后更改',
+  'en-US': 'Async demo, changing in 2 seconds'
+}

-  const onChange = useDebounce((value: string | number) => {
-    toastShow('异步演示 2 秒后更改', 'loading')
+  const onChange = useDebounce((value: string | number) => {
+    toastShow(messages[locale], 'loading')
     setTimeout(() => {
       setInputValue(Number(value))
       SetShow(false)
-    }, 2000)
+    }, ASYNC_DELAY)
-  }, 300)
+  }, DEBOUNCE_DELAY)
src/packages/inputnumber/doc.en-US.md (2)

124-124: 建议:更新废弃属性的文档说明

建议在文档中明确说明 async 属性被废弃的原因,以及用户应该迁移到 beforeChange 的具体步骤。这样可以帮助用户更好地理解和适应这个变更。

建议添加如下说明:

- | ~~async~~`2.8.0` | Support for asynchronous modification | `boolean` | `false` |
+ | ~~async~~`2.8.0` | Support for asynchronous modification (已废弃。请使用 `beforeChange` 属性来处理异步验证逻辑) | `boolean` | `false` |

127-127: 建议:补充 beforeChange 的使用示例

新增的 beforeChange 属性文档说明比较简单,建议添加具体的使用示例,特别是异步验证的场景,以帮助用户更好地理解如何使用这个新特性。

建议在属性说明后添加示例代码:

| beforeChange`2.8.0` | Callback function before the input value changes, return false to prevent input, support returning Promise | `(value: number \| string) => boolean \| Promise<boolean>` | `-` |
+ 
+ Example:
+ ```tsx
+ // 同步验证
+ <InputNumber
+   beforeChange={(value) => {
+     return value > 0;  // 只允许输入正数
+   }}
+ />
+ 
+ // 异步验证
+ <InputNumber
+   beforeChange={async (value) => {
+     const response = await validateNumber(value);
+     return response.isValid;
+   }}
+ />
+ ```
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 16fb6e5 and 31b4667.

📒 Files selected for processing (8)
  • src/packages/inputnumber/demos/h5/demo8.tsx (1 hunks)
  • src/packages/inputnumber/demos/taro/demo8.tsx (2 hunks)
  • src/packages/inputnumber/doc.en-US.md (1 hunks)
  • src/packages/inputnumber/doc.md (1 hunks)
  • src/packages/inputnumber/doc.taro.md (1 hunks)
  • src/packages/inputnumber/doc.zh-TW.md (1 hunks)
  • src/packages/inputnumber/inputnumber.taro.tsx (7 hunks)
  • src/packages/inputnumber/inputnumber.tsx (7 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/packages/inputnumber/inputnumber.tsx

[error] 206-206: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/packages/inputnumber/inputnumber.taro.tsx

[error] 209-209: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (9)
src/packages/inputnumber/inputnumber.tsx (1)

31-31: 添加 beforeChange 属性以支持异步校验

新增的 beforeChange 属性增强了组件的可控性,允许在值改变前进行异步验证,确保输入的有效性。

src/packages/inputnumber/inputnumber.taro.tsx (1)

33-33: 添加 beforeChange 属性以支持异步校验

新增的 beforeChange 属性使组件在值变化前可以进行异步验证,增强了组件的灵活性和可控性。

src/packages/inputnumber/demos/h5/demo8.tsx (2)

6-19: 引入 useDebounce 自定义 Hook 优化性能

添加了 useDebounce 自定义 Hook,对 onChange 方法进行了防抖处理,优化了组件的性能,避免了过于频繁的状态更新。


38-38: 调整 min 属性以支持更大范围的输入

InputNumber 组件的 min 属性从 -6 修改为 -9999,扩展了可输入的数值范围,更好地满足了业务需求。

src/packages/inputnumber/demos/taro/demo8.tsx (1)

47-49: 验证最小值限制的合理性

当前设置的最小值为 -9999,这个范围可能过大。建议:

  1. 根据业务需求设置合理的最小值
  2. 考虑添加输入验证以防止潜在的数值溢出
src/packages/inputnumber/doc.md (1)

124-127: 文档更新清晰完整

文档变更合理地反映了组件的更新:

  1. 标记了 async 属性的废弃
  2. 新增了 beforeChange 回调函数
  3. 补充了 select 属性的版本信息
src/packages/inputnumber/doc.zh-TW.md (1)

116-119: 文档翻译保持一致

繁体中文版本的文档变更与简体中文版本保持一致,翻译准确。

src/packages/inputnumber/doc.taro.md (1)

117-119: Taro 文档更新完整

Taro 版本的文档变更与其他版本保持一致,变更内容完整。

src/packages/inputnumber/doc.en-US.md (1)

125-125: 版本标注正确

select 属性的版本标注清晰地表明了该特性是在 2.7.0 版本引入的。

src/packages/inputnumber/inputnumber.tsx Show resolved Hide resolved
src/packages/inputnumber/inputnumber.taro.tsx Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/packages/inputnumber/__tests__/inputnumber.spec.tsx (3)

Line range hint 12-32: 异步处理的改进很好,建议进一步优化测试用例!

异步包装和 act 的使用是正确的,这样可以确保状态更新完成后再进行断言。不过建议将相关的断言也包装在 await waitFor 中,以确保更好的可靠性。

  await act(async () => {
    fireEvent.click(iconPlus)
  })
- expect(overlimit).not.toBeCalled()
- expect(add).toHaveBeenCalled()
- expect(change.mock.calls[0][0]).toBe(3)
+ await waitFor(() => {
+   expect(overlimit).not.toBeCalled()
+   expect(add).toHaveBeenCalled()
+   expect(change.mock.calls[0][0]).toBe(3)
+ })

Line range hint 35-55: 建议与加号按钮测试保持一致的异步处理方式

这个测试用例的异步改进方向是对的,建议也使用 waitFor 来包装断言,以保持与加号按钮测试的一致性。

  await act(async () => {
    fireEvent.click(iconMinus)
  })
- expect(overlimit).not.toBeCalled()
- expect(reduce).toBeCalled()
- expect(change.mock.calls[0][0]).toBe(1)
+ await waitFor(() => {
+   expect(overlimit).not.toBeCalled()
+   expect(reduce).toBeCalled()
+   expect(change.mock.calls[0][0]).toBe(1)
+ })

174-184: 建议增强超限输入测试的完整性

虽然异步处理正确,但建议增加更多断言来全面测试超限情况:

  1. 验证输入值是否被正确限制
  2. 验证 overlimit 回调的参数
  await act(async () => {
    fireEvent.input(input)
  })
- expect(overlimit).toBeCalled()
+ await waitFor(() => {
+   expect(overlimit).toHaveBeenCalledWith(200)
+   expect(input.value).toBe('100')
+ })
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 31b4667 and c91aa96.

📒 Files selected for processing (1)
  • src/packages/inputnumber/__tests__/inputnumber.spec.tsx (8 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (5)
src/packages/inputnumber/__tests__/inputnumber.spec.tsx (5)

2-2: 导入 act 函数是正确的做法!

从 @testing-library/react 导入 act 函数对于处理异步操作是必要的,这符合 React 测试的最佳实践。


Line range hint 57-78: 异步处理正确,建议统一使用 waitFor

异步改动符合预期,建议统一使用 waitFor 来处理断言,以确保测试的稳定性。


Line range hint 80-102: 异步处理方式正确,保持一致性很重要

异步改动符合预期,建议与其他测试用例保持一致的异步处理方式。


116-127: readonly 属性的异步测试处理得当

异步包装的添加是正确的,测试逻辑完整地验证了 readonly 属性的行为。


129-138: 小数步进值的异步测试实现合理

异步处理的添加确保了小数计算的准确性验证,测试逻辑完善。

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

Successfully merging this pull request may close these issues.

InputNumber组件使用allowEmpty没有效果,在官方的demo中也是如此。
1 participant