Skip to content

Conversation

irisSong
Copy link
Collaborator

@irisSong irisSong commented Feb 14, 2025

🤔 这个变动的性质是?

  • 新特性提交
  • 日常 bug 修复
  • 站点、文档改进
  • 演示代码改进
  • 组件样式/交互改进
  • TypeScript 定义更新
  • 包体积优化
  • 性能优化
  • 功能增强
  • 国际化改进
  • 重构
  • 代码风格优化
  • 测试用例
  • 分支合并
  • 其他改动(是关于什么的改动?)

🔗 相关 Issue

💡 需求背景和解决方案

☑️ 请求合并前的自查清单

⚠️ 请自检并全部勾选全部选项⚠️

  • 文档已补充或无须补充
  • 代码演示已提供或无须提供
  • TypeScript 定义已补充或无须补充
  • fork仓库代码是否为最新避免文件冲突
  • Files changed 没有 package.json lock 等无关文件

Summary by CodeRabbit

  • 新功能
    • 新增 PickerView 组件,为用户提供全新的选择视图体验。
  • 重构
    • 优化了数据录入、日期选择器和选择器组件的交互逻辑,统一了显示属性,增强了稳定性。
    • 移除了 PickerOption 接口,采用新的 PickerOptions 和 PickerValue 类型,提升了类型安全性。
    • 更新了多个组件的参数类型,确保一致性和类型安全。
    • 更新了 Picker 组件的内部状态管理,简化了选项处理逻辑,提升了可读性和维护性。
  • 样式
    • 精简并优化了选择器组件的样式,实现了界面更现代、简洁的视觉效果。

@irisSong irisSong requested a review from xiaoyatong February 14, 2025 10:07
Copy link
Collaborator

@xiaoyatong xiaoyatong left a comment

Choose a reason for hiding this comment

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

1、弹出时,没有动效了
2、建议默认有值被选中,参考线上
image
3、datepicker 平闰年处理:慢慢往上拖年份的时候会出现。
image

const columns = container.querySelectorAll('.nut-picker-list')[0]
const lists = columns.querySelectorAll('.nut-picker-roller-item-title')
const years = ['2020', '2021', '2022']
const columns = container.querySelectorAll('.nut-pickerview-list')[0]
Copy link
Collaborator

Choose a reason for hiding this comment

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

参考 ai 反馈

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

参考 ai 反馈

已修改

import { BasicComponent, ComponentDefaults } from '@/utils/typings'
import { isDate } from '@/utils/is-date'
import { padZero } from '@/utils/pad-zero'
import { PickerOptionItem, PickerValue } from '@/packages/pickerview/index.taro'
Copy link
Collaborator

@xiaoyatong xiaoyatong Feb 25, 2025

Choose a reason for hiding this comment

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

这里是否可以直接引用 types.ts

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

这里是否可以直接引用 types.ts

已修改

>
formatter: (type: string, option: PickerOption) => PickerOption
filter: (type: string, option: PickerOption[]) => PickerOption[]
formatter: (type: string, option: PickerOptionItem) => PickerOptionItem
Copy link
Collaborator

Choose a reason for hiding this comment

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

我个人理解这里不需要突出 item,PickerOption 和 PickerOptions 可以标明他们的单复数~

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

我个人理解这里不需要突出 item,PickerOption 和 PickerOptions 可以标明他们的单复数~

已修改

onConfirm: (
selectedOptions: PickerOption[],
selectedValue: (string | number)[]
selectedOptions: PickerOptionItem[],
Copy link
Collaborator

Choose a reason for hiding this comment

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

这里 可以直接使用 PickerOptions 了,types 有定义。

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

这里 可以直接使用 PickerOptions 了,types 有定义。

已修改

SafeArea,
Popup,
PopupProps,
} from '@nutui/nutui-react'
Copy link
Collaborator

Choose a reason for hiding this comment

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

引相对路径就可以。

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

引相对路径就可以。
已修改

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

♻️ Duplicate comments (2)
src/packages/picker/demos/h5/demo7.tsx (1)

54-87: 🛠️ Refactor suggestion

优化异步数据更新逻辑

当前代码存在以下需要优化的地方:

  1. 直接修改状态数组可能导致意外的副作用
  2. 使用 setTimeout(fn, 0) 是一种反模式

建议使用不可变的方式更新状态:

-      asyncData[0][1].children = [
-        // ... data
-      ]
-      setAsyncData([...[...asyncData]])
+      setAsyncData((prevData) => {
+        const newData = JSON.parse(JSON.stringify(prevData))
+        newData[0][1].children = [
+          // ... data
+        ]
+        return newData
+      })

对于异步数据加载,建议:

  1. 使用 Promise 或 async/await
  2. 添加加载状态指示
  3. 实现错误处理机制
src/packages/picker/demos/taro/demo7.tsx (1)

54-87: 🛠️ Refactor suggestion

优化异步数据更新逻辑

当前代码存在以下需要优化的地方:

  1. 直接修改状态数组可能导致意外的副作用
  2. 使用 setTimeout(fn, 0) 是一种反模式

建议使用不可变的方式更新状态:

-      asyncData[0][1].children = [
-        // ... data
-      ]
-      setAsyncData([...[...asyncData]])
+      setAsyncData((prevData) => {
+        const newData = JSON.parse(JSON.stringify(prevData))
+        newData[0][1].children = [
+          // ... data
+        ]
+        return newData
+      })

对于异步数据加载,建议:

  1. 使用 Promise 或 async/await
  2. 添加加载状态指示
  3. 实现错误处理机制
🧹 Nitpick comments (4)
src/packages/pickerview/__test__/pickerview.spec.tsx (1)

161-166: 考虑使用 act 和 waitFor 优化测试

建议重构测试逻辑,使用 actwaitFor 而不是依赖 setTimeout,这样可以确保测试的稳定性。

-  const { container } = render(<PenderContent />)
-
-  await waitFor(() => {
-    expect(container).toMatchSnapshot()
-  })
+  const { container } = render(<PenderContent />)
+
+  await act(async () => {
+    await waitFor(() => {
+      expect(container).toMatchSnapshot()
+    })
+  })
src/packages/datepicker/demos/h5/demo2.tsx (1)

16-18: 参数类型和实现更新

函数参数类型从 (values: (string | number)[], options: PickerOption[]) 更改为 (values: PickerValue[], options: PickerOptions),并且在映射函数中使用 option.label 替代了 option.text

控制台日志输出可帮助调试,但在生产环境中可能需要移除。

考虑在生产环境中移除控制台日志输出:

-  const confirm = (values: PickerValue[], options: PickerOptions) => {
-    console.log('values', values, options)
-    setDesc(options.map((option) => option.label).join('-'))
+  const confirm = (values: PickerValue[], options: PickerOptions) => {
+    setDesc(options.map((option) => option.label).join('-'))
src/packages/datepicker/datepicker.tsx (1)

414-420: 使用可选链优化代码

根据静态分析工具的建议,这段代码可以使用可选链操作符来优化:

-          onConfirm={(
-            selectedOptions: PickerOptions,
-            selectedValue: PickerValue[]
-          ) => onConfirm && onConfirm(selectedOptions, selectedValue)}
+          onConfirm={(
+            selectedOptions: PickerOptions,
+            selectedValue: PickerValue[]
+          ) => onConfirm?.(selectedOptions, selectedValue)}

使用可选链可以简化代码并保持同样的功能。

🧰 Tools
🪛 Biome (1.9.4)

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

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

420-423: 建议使用可选链操作符

在调用 onConfirm 函数时可以使用可选链操作符,以简化代码并提高可读性。

-onConfirm={(selectedOptions: PickerOptions, selectedValue: PickerValue[]) => onConfirm && onConfirm(selectedOptions, selectedValue)}
+onConfirm={(selectedOptions: PickerOptions, selectedValue: PickerValue[]) => onConfirm?.(selectedOptions, selectedValue)}
🧰 Tools
🪛 Biome (1.9.4)

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f6edf91 and 9688104.

📒 Files selected for processing (41)
  • src/packages/datepicker/__test__/datepicker.spec.tsx (6 hunks)
  • src/packages/datepicker/datepicker.taro.tsx (8 hunks)
  • src/packages/datepicker/datepicker.tsx (8 hunks)
  • src/packages/datepicker/demos/h5/demo1.tsx (3 hunks)
  • src/packages/datepicker/demos/h5/demo2.tsx (2 hunks)
  • src/packages/datepicker/demos/h5/demo3.tsx (2 hunks)
  • src/packages/datepicker/demos/h5/demo4.tsx (2 hunks)
  • src/packages/datepicker/demos/h5/demo5.tsx (2 hunks)
  • src/packages/datepicker/demos/h5/demo6.tsx (2 hunks)
  • src/packages/datepicker/demos/h5/demo7.tsx (2 hunks)
  • src/packages/datepicker/demos/h5/demo8.tsx (3 hunks)
  • src/packages/datepicker/demos/taro/demo1.tsx (2 hunks)
  • src/packages/datepicker/demos/taro/demo2.tsx (1 hunks)
  • src/packages/datepicker/demos/taro/demo3.tsx (2 hunks)
  • src/packages/datepicker/demos/taro/demo4.tsx (2 hunks)
  • src/packages/datepicker/demos/taro/demo5.tsx (2 hunks)
  • src/packages/datepicker/demos/taro/demo6.tsx (2 hunks)
  • src/packages/datepicker/demos/taro/demo7.tsx (2 hunks)
  • src/packages/datepicker/demos/taro/demo8.tsx (3 hunks)
  • src/packages/picker/demos/h5/demo1.tsx (2 hunks)
  • src/packages/picker/demos/h5/demo6.tsx (1 hunks)
  • src/packages/picker/demos/h5/demo7.tsx (2 hunks)
  • src/packages/picker/demos/h5/demo8.tsx (2 hunks)
  • src/packages/picker/demos/taro/demo1.tsx (2 hunks)
  • src/packages/picker/demos/taro/demo6.tsx (1 hunks)
  • src/packages/picker/demos/taro/demo7.tsx (2 hunks)
  • src/packages/picker/demos/taro/demo8.tsx (2 hunks)
  • src/packages/picker/picker.taro.tsx (6 hunks)
  • src/packages/picker/picker.tsx (6 hunks)
  • src/packages/pickerview/__test__/pickerview.spec.tsx (1 hunks)
  • src/packages/pickerview/doc.en-US.md (1 hunks)
  • src/packages/pickerview/doc.md (1 hunks)
  • src/packages/pickerview/doc.taro.md (1 hunks)
  • src/packages/pickerview/doc.zh-TW.md (1 hunks)
  • src/packages/pickerview/index.taro.ts (1 hunks)
  • src/packages/pickerview/index.ts (1 hunks)
  • src/packages/pickerview/pickerroller.taro.tsx (5 hunks)
  • src/packages/pickerview/pickerroller.tsx (5 hunks)
  • src/packages/pickerview/pickerview.taro.tsx (7 hunks)
  • src/packages/pickerview/pickerview.tsx (7 hunks)
  • src/packages/pickerview/types.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (16)
  • src/packages/datepicker/demos/h5/demo4.tsx
  • src/packages/datepicker/test/datepicker.spec.tsx
  • src/packages/datepicker/demos/h5/demo3.tsx
  • src/packages/datepicker/demos/taro/demo3.tsx
  • src/packages/datepicker/demos/taro/demo7.tsx
  • src/packages/datepicker/demos/h5/demo7.tsx
  • src/packages/datepicker/demos/taro/demo2.tsx
  • src/packages/datepicker/demos/taro/demo6.tsx
  • src/packages/datepicker/demos/h5/demo5.tsx
  • src/packages/datepicker/demos/taro/demo8.tsx
  • src/packages/picker/demos/h5/demo1.tsx
  • src/packages/picker/demos/h5/demo8.tsx
  • src/packages/datepicker/demos/taro/demo1.tsx
  • src/packages/datepicker/demos/taro/demo4.tsx
  • src/packages/datepicker/demos/h5/demo6.tsx
  • src/packages/datepicker/demos/h5/demo1.tsx
🧰 Additional context used
🧠 Learnings (1)
src/packages/pickerview/__test__/pickerview.spec.tsx (1)
Learnt from: xiaoyatong
PR: jdf2e/nutui-react#2990
File: src/packages/pickerview/__test__/pickerview.spec.tsx:0-0
Timestamp: 2025-02-25T02:21:32.906Z
Learning: In React component tests, avoid using setTimeout with fixed delays. Instead, use act() to wrap async state updates and waitFor() for assertions, which makes tests more stable and reliable.
🪛 GitHub Check: codecov/patch
src/packages/picker/picker.tsx

[warning] 223-225: src/packages/picker/picker.tsx#L223-L225
Added lines #L223 - L225 were not covered by tests


[warning] 230-230: src/packages/picker/picker.tsx#L230
Added line #L230 was not covered by tests

🪛 Biome (1.9.4)
src/packages/datepicker/datepicker.tsx

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

src/packages/datepicker/datepicker.taro.tsx

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (100)
src/packages/pickerview/index.ts (1)

5-5: 类型导出命名调整为更一致的形式

PickerOptionItem 重命名为 PickerOption 使类型命名更加简洁和一致,这有助于简化代码库中的类型引用。

src/packages/pickerview/__test__/pickerview.spec.tsx (2)

136-136: 增强类型安全,明确状态变量类型

value 状态变量添加显式类型注解 [] as number[] 提高了类型安全性,明确了数组元素只能是数字类型。


139-146: 🛠️ Refactor suggestion

异步更新测试需要优化

当前的异步测试使用了固定的延时时间(1000ms),这可能导致测试不稳定。建议使用 act 包装异步操作,并考虑使用更可靠的等待机制。

-    useEffect(() => {
-      const timer = setTimeout(() => {
-        setInnerOptions(listData)
-        setValue([1])
-      }, 1000)
-
-      return () => clearTimeout(timer) // 清理定时器
-    }, [])
+    useEffect(() => {
+      setInnerOptions(listData)
+      setValue([1])
+    }, [])
src/packages/pickerview/index.taro.ts (1)

5-5: 统一类型命名约定

PickerOptionItem 更新为 PickerOption,与非 Taro 版本保持一致,确保代码库中的类型命名统一。

src/packages/pickerview/pickerroller.taro.tsx (5)

11-11: 更新导入的类型名称

将导入类型 PickerOptionItem 更新为 PickerOption,保持整个代码库中类型命名的一致性。


26-26: 更新函数参数类型

renderLabel 函数参数 item 的类型从 PickerOptionItem 更新为 PickerOption,确保类型一致性。


135-137: 增加明确的类型注解

findIndex 方法中为 item 参数添加了明确的 PickerOption 类型注解,提高了代码的类型安全性。


228-228: 为映射函数参数添加类型注解

options.map 回调函数的参数添加了明确的类型注解,提高了代码的类型安全性和可读性。


241-241: 为非 3D 视图映射函数参数添加类型注解

同样在非 3D 视图的 options.map 回调函数中添加了明确的类型注解,保持了代码风格一致性。

src/packages/pickerview/doc.zh-TW.md (2)

74-74: 类型命名更新

这里将标题从 PickerOptionItem 更改为 PickerOption,与代码库中的类型重命名保持一致。这种更新有助于维护文档与代码之间的一致性。


80-80: 类型定义更新

children 属性的类型从 PickerOptionItem[] 更改为 PickerOptions,与代码库中的类型重构保持一致。这样的改动有助于提高类型安全性和代码可读性。

src/packages/datepicker/demos/taro/demo5.tsx (2)

2-7: 导入类型更新

@nutui/nutui-react-taro 导入 PickerValuePickerOptions 类型,替换了之前使用的 PickerOption 类型,与整体重构方向一致。


18-19: 函数参数类型和属性访问方式更新

  1. confirm 函数的参数类型从 PickerOption[](string | number)[] 更新为 PickerOptionsPickerValue[]
  2. 将属性访问从 option.text 更改为 option.label

这些变更与整个代码库中的类型重构和属性命名规范更新保持一致。

src/packages/pickerview/pickerview.tsx (8)

15-15: 导入类型重命名

将导入的类型从 PickerOptionItem 更改为 PickerOption,保持与整个代码库的类型重命名一致。


26-26: 函数参数类型更新

renderLabel 函数的参数类型从 PickerOptionItem 更新为 PickerOption,确保与重命名的类型定义保持一致。


79-79: 变量类型声明更新

columnOptions 变量的类型从 PickerOptionItem 更新为 PickerOption,与类型重命名保持一致。


97-97: 回调函数参数类型更新

findIndex 回调函数中参数的类型注解从 PickerOptionItem 更新为 PickerOption,确保类型一致性。


133-133: 事件处理函数参数类型更新

handleSelect 函数的参数类型从 PickerOptionItem 更新为 PickerOption,保持类型定义的一致性。


161-161: 类型断言更新

optionFirst 的类型断言从 PickerOptionItem[] 更新为 PickerOptions,保持与新的类型命名约定一致。


179-179: 回调函数参数类型更新

find 回调函数中参数的类型注解从 PickerOptionItem 更新为 PickerOption,确保类型一致性。


184-184: 返回值类型断言更新

将过滤后数组的类型断言从 PickerOptionItem[] 更新为 PickerOptions,与整体类型重构保持一致。

src/packages/pickerview/doc.md (2)

74-74: 类型命名更新

这里将标题从 PickerOptionItem 更改为 PickerOption,与代码库中的类型重命名保持一致。这种更新有助于维护文档与代码之间的一致性。


80-80: 类型定义更新

children 属性的类型从 PickerOptionItem[] 更改为 PickerOptions,与代码库中的类型重构保持一致。这样的改动有助于提高类型安全性和代码可读性。

src/packages/pickerview/doc.taro.md (2)

74-74: 类型重命名更新

类型名称从 PickerOptionItem 更改为 PickerOption,保持了命名上的一致性,符合组件库的整体重构方向。


80-80: 级联选项类型更新

children 属性的类型从 PickerOptionItem[] 更改为 PickerOptions,类型定义更加统一,有利于提高代码的一致性和可维护性。

src/packages/datepicker/demos/h5/demo2.tsx (1)

2-7: 类型导入更新

从组件库中导入了 PickerOptionsPickerValue 类型来替代之前的 PickerOption,符合类型系统的重构方向。

src/packages/pickerview/pickerview.taro.tsx (8)

16-17: 导入类型更新

更新导入的类型名称,从 PickerOptionItem 更改为 PickerOption,保持类型系统的一致性。


27-28: 渲染函数参数类型更新

renderLabel 函数的参数类型从 PickerOptionItem 更新为 PickerOption,与新的类型定义保持一致。


80-84: 变量类型定义更新

columnOptions 变量的类型从 PickerOptionItem 更新为 PickerOption,属性名称保持一致且符合类型系统的变更。


98-99: 回调函数参数类型更新

findIndex 方法的回调函数参数类型从 PickerOptionItem 更新为 PickerOption,保持类型系统一致性。


134-135: 函数参数类型更新

handleSelect 函数的参数类型从 PickerOptionItem 更新为 PickerOption,与整体类型系统变更保持一致。


162-163: 类型转换更新

optionFirst 变量的类型转换从 PickerOptionItem[] 更新为 PickerOptions,确保类型一致性。


180-181: 回调函数参数类型更新

find 方法的回调函数参数类型从 PickerOptionItem 更新为 PickerOption,保持类型系统的一致性。


185-186: 返回类型更新

filter 方法的返回类型从 PickerOptionItem[] 更新为 PickerOptions,确保类型转换的正确性和一致性。

src/packages/pickerview/doc.en-US.md (2)

74-74: 类型名称更新

英文文档中将类型名称从 PickerOptionItem 更改为 PickerOption,与中文文档保持一致,确保文档的统一性。


80-80: 级联选项类型更新

英文文档中将 children 属性的类型从 PickerOptionItem[] 更改为 PickerOptions,与中文文档保持一致,确保类型系统的统一性。

src/packages/picker/demos/taro/demo8.tsx (3)

2-9: 导入类型定义更新

引入了新的类型定义 PickerOptionsPickerValue,更好地规范了组件的类型约束。这与整体重构中对 Picker 相关类型的统一调整保持一致。


28-36: 参数类型和属性访问更新

函数参数类型从 PickerOption[] 更新为更明确的 PickerOptions 类型,同时将属性访问从 option.text 更改为 option.label。这样的变更保持了与其他 Picker 组件的一致性。


55-61: 组件样式属性和事件处理更新

样式属性和事件处理函数签名已更新,使用了新的类型定义。这些变更使组件接口更加一致和类型安全。

src/packages/pickerview/pickerroller.tsx (4)

10-10: 类型导入更新

PickerOptionItem 更新为 PickerOption,保持与整个库中类型定义的一致性。


24-24: 渲染标签函数参数类型更新

renderLabel 函数的参数类型从 PickerOptionItem 更新为 PickerOption,确保类型一致性。


133-135: 查找索引回调函数类型更新

findIndex 方法中明确指定了回调函数参数的类型为 PickerOption,提高了代码的类型安全性。


215-215: 映射函数参数类型更新

options.map 函数调用中显式指定了 item 参数的类型为 PickerOption,增强了代码的类型安全性和可读性。

Also applies to: 228-228

src/packages/picker/demos/taro/demo6.tsx (5)

2-8: 导入类型定义更新

引入了新的类型定义 PickerOptionsPickerValue,更好地规范了组件的类型约束。这与整体重构中对 Picker 相关类型的统一调整保持一致。


12-13: 状态管理优化

添加了新的 value 状态变量并初始化为特定值,同时为 cityCustom 提供了默认值。这样可以确保组件初始化时有合理的默认值,提高用户体验。


14-73: 建议提取共享的数据和工具函数

h5 和 taro 版本的 demo 中存在大量重复的数据结构和逻辑。建议将这些共同部分提取到共享文件中。

建议创建一个共享的数据文件:

// shared/cityData.ts
export const customCityData = [
  [
    {
      value: 1,
      label: '北京',
      children: [
        // ... existing data
      ],
    },
    // ... remaining data
  ],
]

然后在两个 demo 文件中导入:

-const customCityData = [ ... ]
+import { customCityData } from '../shared/cityData'

75-85: 回调函数参数类型和属性访问更新

setChooseValueCustom 函数的参数类型更新为 PickerOptionsPickerValue[],同时属性访问从 item.text 更改为 item.label。这样的变更与整体重构中的类型调整保持一致,提高了代码的类型安全性。


98-103: 事件处理函数更新

更新了 value 属性和事件处理函数,使用了新的类型定义。onChange 函数参数使用解构赋值,代码更加简洁。

src/packages/datepicker/demos/h5/demo8.tsx (4)

2-8: 导入类型定义更新

引入了新的类型定义 PickerOptionsPickerValue,更好地规范了组件的类型约束。这与整体重构中对 DatePicker 相关类型的统一调整保持一致。


20-22: 确认函数参数类型更新

confirm 函数的参数类型从 (values: (string | number)[], options: PickerOption[]) 更新为 (values: PickerValue[], options: PickerOptions),同时属性访问使用新的 label 属性。这些变更与统一的类型定义保持一致。


23-28: 过滤函数参数类型更新

filter 函数的参数类型从 options: PickerOption[] 更新为 options: PickerOptions,使类型定义更加统一。


29-47: 格式化函数属性访问更新

formatter1 函数中,将对选项的属性访问从 option.text 更改为 option.label。这样的变更保持了与其他 Picker 组件的一致性,提高了代码的可维护性。

src/packages/picker/demos/taro/demo1.tsx (5)

2-9: 导入更新适应类型更改

导入了新的类型定义,这对重构后的 Picker 组件是必要的。引入 PickerOptionsPickerValuePickerOnChangeCallbackParameter 类型有助于提高类型安全性。


14-26: 属性名称从 text 更改为 label

将数组名从 listData1 更改为更具描述性的 options,并且将对象属性从 text 更改为 label,符合组件重构的一致性要求。


27-33: 回调函数签名优化

从使用多个独立参数改为使用单个结构化参数,提高了函数接口的清晰度和可维护性。


34-44: 确认函数参数类型更新

确认函数参数类型已更新为新的 PickerOptionsPickerValue[] 类型,并相应地更新了函数内部逻辑,使用 option.label 替代原来的 option.text


55-59: Picker 组件属性更新

Picker 组件的属性已更新以适应新的类型和命名约定,传递 options 数组和回调函数。

src/packages/picker/demos/h5/demo7.tsx (5)

2-9: 导入更新适应类型更改

导入了新的类型定义,这对重构后的 Picker 组件是必要的。引入 PickerOptionsPickerValuePickerOnChangeCallbackParameter 类型有助于提高类型安全性。


13-14: 状态初始化使用新的类型

使用 TypeScript 泛型 PickerValue[] 初始化 value 状态,并为 asyncDesc 提供默认值,增强了类型安全性和代码可读性。


15-53: 数据结构更新使用 label 替代 text

数据结构已更新为使用 label 代替 text,保持了与重构的一致性。


88-98: 确认函数参数类型更新

确认函数参数类型已更新为新的 PickerOptionsPickerValue[] 类型,并相应地更新了函数内部逻辑,使用 option.label 替代原来的 option.text。同时添加了 setValue 调用来更新状态。


107-115: Picker 组件属性更新

Picker 组件的属性已更新以适应新的类型和命名约定,传递 value 状态和更新的回调函数。

src/packages/picker/demos/taro/demo7.tsx (5)

2-9: 导入更新适应类型更改

导入了新的类型定义,这对重构后的 Picker 组件是必要的。引入 PickerOptionsPickerValuePickerOnChangeCallbackParameter 类型有助于提高类型安全性。


13-14: 状态初始化使用新的类型

使用 TypeScript 泛型 PickerValue[] 初始化 value 状态,并为 asyncDesc 提供默认值,增强了类型安全性和代码可读性。


15-53: 数据结构更新使用 label 替代 text

数据结构已更新为使用 label 代替 text,保持了与重构的一致性。


88-98: 确认函数参数类型更新

确认函数参数类型已更新为新的 PickerOptionsPickerValue[] 类型,并相应地更新了函数内部逻辑,使用 option.label 替代原来的 option.text。同时添加了 setValue 调用来更新状态。


107-115: Picker 组件属性更新

Picker 组件的属性已更新以适应新的类型和命名约定,传递 value 状态和更新的回调函数。

src/packages/picker/demos/h5/demo6.tsx (6)

2-8: 导入更新适应类型更改

导入了新的类型定义,这对重构后的 Picker 组件是必要的。引入 PickerOptionsPickerValue 类型有助于提高类型安全性。


12-13: 状态初始化使用新的类型

使用 TypeScript 泛型 PickerValue[] 初始化 value 状态,并为 cityCustom 提供默认值 '上海',增强了类型安全性和用户体验。


14-73: 数据结构更新使用 label 替代 text

数据结构已更新为使用 label 代替 text,保持了与重构的一致性。嵌套的子选项也进行了相应更新。


75-85: 选择值函数参数类型更新

选择值函数参数类型已更新为新的 PickerOptionsPickerValue[] 类型,并相应地更新了函数内部逻辑,使用 item.label 替代原来的 item.text。同时添加了 setValue 调用来更新状态。


89-93: Cell 组件标题更新

Cell 组件的标题从"多级联动"更改为"请选择城市",使界面文本更加明确和一致。


98-104: Picker 组件属性和回调更新

Picker 组件添加了 value 属性并更新了 onChange 回调的实现,使用了解构赋值来获取参数,提高了代码的可读性。回调函数中的控制台输出也更新为使用新的参数名称。

src/packages/picker/picker.taro.tsx (7)

8-24: 优化了导入和类型定义

代码重构后,使用了更清晰的类型结构,从 pickerview 模块导入了更通用的类型定义。同时添加了必要的组件导入,如 PickerView 和 SafeArea,使得代码结构更加模块化。


29-49: 类型定义更加明确和统一

接口 PickerProps 的类型定义得到优化:

  • options 从 (PickerOption | PickerOption[])[] 变为更简洁的 PickerOptions[]
  • value 和 defaultValue 更新为 PickerValue[]
  • 回调函数签名更新,使用了更明确的类型

这些变更使得类型系统更加一致,提高了代码的可维护性。


115-119: 状态管理逻辑优化

重构后的状态管理更加清晰:

  • 使用了更明确的状态变量命名
  • 添加了引用类型的状态管理
  • 使用 useState 和 useRef 结合管理复杂状态

这种方式既保证了状态更新的性能,又提高了代码的可读性。


128-145: 回调处理逻辑优化

onChangeItem 函数重构得很好:

  • 使用解构赋值简化参数处理
  • 通过 isEqual 避免不必要的状态更新
  • 通过引用更新 selectedOptionsRef 确保数据一致性

这种方式可以减少不必要的渲染并提高组件性能。


191-213: UI 渲染逻辑更加模块化

使用 renderPickerElement 函数封装渲染逻辑,这是一个很好的重构:

  • 将复杂的渲染逻辑封装到单独的函数中
  • 使用新的 PickerView 组件替代旧的实现
  • 清晰地传递所需的属性和回调

这使得代码更加可读,也便于维护。


219-232: Popup 组件使用优化

Popup 组件的使用变得更加简洁和条件化:

  • 使用条件渲染避免不必要的组件实例化
  • 添加了 SafeArea 组件提高在不同设备上的显示效果
  • 简化了 onOverlayClick 处理逻辑

这些变更提高了组件的性能和用户体验。


237-237: 类型导出更加准确

forwardRef 的类型从 unknown 更新为具体的 PickerRef,这可以提供更好的类型安全性和自动补全支持。

src/packages/picker/picker.tsx (4)

9-23: 优化了导入和类型定义

类似于 Taro 版本,Web 版本也更新了导入和类型定义,保持了两个平台的一致性。使用了 pickerview 模块中的类型,简化了类型结构。


28-48: 统一的接口定义

PickerProps 接口的更新与 Taro 版本保持一致,确保了跨平台的类型一致性。这种统一的类型定义有助于减少平台特定的代码差异。


114-118: 状态管理优化

同样优化了状态管理,使用相同的模式管理状态。这种一致性有助于跨平台代码的维护和理解。


190-213: UI 渲染模块化

使用 renderPickerElement 函数封装渲染逻辑,提高代码的可读性和可维护性。Web 版本使用 div 和 span 元素而不是 View 组件,符合 Web 平台的特性。

src/packages/pickerview/types.ts (4)

5-11: 类型结构优化

重构后的类型定义更加清晰:

  • PickerOption 作为基本类型单元
  • 定义 PickerOptions 作为 PickerOption 的数组类型
  • 明确了属性名称,使用 label 替代之前的 text

这种类型结构使得代码更加自解释,同时保持了类型的一致性。


13-21: 接口更新与类型一致

PickerRollerProps 接口的更新与新的类型定义保持一致:

  • options 类型更新为 PickerOptions
  • onSelect 和 renderLabel 函数签名更新为使用 PickerOption

这确保了类型系统的一致性,减少了潜在的类型错误。


23-27: 回调参数类型更新

PickerOnChangeCallbackParameter 接口的 selectedOptions 属性类型从数组更新为 PickerOptions,与整体类型系统保持一致。这种一致性使得类型检查更加可靠。


29-38: PickerViewProps 接口更新

PickerViewProps 接口也进行了相应更新,保持与其他接口的一致性。整个类型系统的一致性是这次重构的一个重要方面,有助于提高代码质量。

src/packages/datepicker/datepicker.tsx (4)

8-12: 导入更新与类型系统一致

从 pickerview 模块导入了新的类型定义,保持与整体类型系统的一致性。这种变更确保了 DatePicker 组件可以无缝使用 Picker 组件的更新。


46-57: 接口更新符合新的类型系统

DatePickerProps 接口的更新与 Picker 组件的类型变更保持一致:

  • filter 方法参数更新为 PickerOptions
  • onConfirm 和 onChange 方法使用新的类型定义

这种一致性确保了组件间的兼容性和类型安全。


111-112: 状态变量类型更新

状态变量 pickerValue 和 pickerOptions 的类型更新为新的类型定义,保持与其他更改的一致性。这是重构的重要部分,确保类型系统的完整性。


320-326: 属性名从 text 改为 label

formatOption 函数返回的对象属性从 text 改为 label,符合新的类型定义。这是一个重要的变更,确保了与新类型系统的兼容性。

src/packages/datepicker/datepicker.taro.tsx (8)

9-13: 导入从单一文件获取类型定义,提高了代码组织性

导入使用了新的类型定义 PickerOptionPickerOptionsPickerValue,这符合类型系统的规范化。


47-47: 参数类型更新为 PickerOptions

filter 函数的参数类型从 PickerOption[] 更新为 PickerOptions,确保了类型一致性。


51-53: 回调函数参数类型更新

onConfirm 回调函数的参数类型从旧的类型更新为 PickerOptionsPickerValue[],与新的类型系统保持一致。


55-58: onChange 回调函数参数类型更新

onChange 回调函数的参数类型也更新为 PickerOptionsPickerValue[],保持了类型系统的一致性。


112-113: 状态类型更新

将状态变量 pickerValuepickerOptions 的类型分别更新为 PickerValue[]PickerOptions[],与新的类型定义保持一致。


321-323: 属性名从 text 更改为 label

将选项的属性名从 text 更改为 label,这是此次重构的核心变更之一,使命名更加直观和统一。


327-327: 返回对象属性名更新

返回对象的属性名从 text 更改为 label,与整体重构保持一致。


424-426: handlePickerChange 调用参数更新

更新了 onChange 回调中 handlePickerChange 的调用,以适应新的参数类型和结构。

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/picker/picker.taro.tsx (2)

145-145: 移除调试代码

这里有一个调试用的 console.log 语句,应该在提交前删除。

-    console.log('sss')

120-126: 优化 useEffect 依赖项

当前的依赖项数组包含 innerOptions,但是这个状态也在 effect 内部被更新,这可能会导致不必要的重新渲染。

  useEffect(() => {
    if (innerVisible) {
      setInnerValue(selectedValue)
      setInnerOptions(options as PickerOptions[])
    }
-  }, [selectedValue, innerOptions, innerVisible])
+  }, [selectedValue, options, innerVisible])
src/packages/picker/picker.tsx (1)

120-126: 优化 useEffect 依赖项

当前的依赖项数组包含 innerOptions,但是这个状态也在 effect 内部被更新,这可能会导致不必要的重新渲染。

  useEffect(() => {
    if (innerVisible) {
      setInnerValue(selectedValue)
      setInnerOptions(options as PickerOptions[])
    }
-  }, [selectedValue, innerOptions, innerVisible])
+  }, [selectedValue, options, innerVisible])
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9688104 and f81ef99.

📒 Files selected for processing (2)
  • src/packages/picker/picker.taro.tsx (7 hunks)
  • src/packages/picker/picker.tsx (6 hunks)
🧰 Additional context used
🪛 GitHub Check: codecov/patch
src/packages/picker/picker.tsx

[warning] 223-224: src/packages/picker/picker.tsx#L223-L224
Added lines #L223 - L224 were not covered by tests

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build
  • GitHub Check: test
🔇 Additional comments (7)
src/packages/picker/picker.taro.tsx (2)

192-215: 组件结构优化良好

将渲染逻辑抽取到 renderPickerElement 函数中是一个很好的做法,它使代码更加模块化和可读。使用 PickerView 替换旧的 PickerPanel 也使组件更加一致。


127-146: 结构化回调参数的良好实践

重构后的 onChangeItem 函数使用结构化参数对象是一个很好的模式,提高了代码的可读性和可维护性。使用 isEqual 来避免不必要的状态更新也是一个优化。

src/packages/picker/picker.tsx (5)

222-225: 为 onOverlayClick 处理器添加测试覆盖

静态分析工具显示这部分代码未被测试覆盖。需要添加单元测试来确保 closeOnOverlayClick 属性的正确行为。

#!/bin/bash
# 检查是否有现有测试覆盖这部分代码
rg -A 2 "onOverlayClick" --glob "**/__tests__/*.spec.tsx"
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 223-224: src/packages/picker/picker.tsx#L223-L224
Added lines #L223 - L224 were not covered by tests


190-213: 模块化渲染函数的良好实践

将渲染逻辑抽取到 renderPickerElement 函数中是一个很好的做法,它使代码更加模块化和可读。这种重构提高了代码的可维护性。


26-51: 类型定义的改进

PickerOptionsPickerValue 类型替换旧的类型定义是一个很好的改进,提高了类型安全性。回调函数签名的更新也使得 API 更加一致和易于使用。


127-144: 结构化的参数处理

新的 onChangeItem 函数使用结构化参数和命名明确的回调参数,这使得代码更易于理解和维护。使用 isEqual 避免不必要的状态更新也是一个良好的优化。


228-228: SafeArea 组件缺少测试

新增的 SafeArea 组件使用缺少测试覆盖,建议添加相应的单元测试来确保其正确渲染。

@irisSong
Copy link
Collaborator Author

1、弹出时,没有动效了 2、建议默认有值被选中,参考线上 image 3、datepicker 平闰年处理:慢慢往上拖年份的时候会出现。 image

1、已修改 2、没有默认值就应该不选中,要不内外不一致 3、暂未复现,待复现再跟进修改

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 (2)
src/packages/picker/picker.taro.tsx (2)

121-126: useEffect 依赖项需优化

当前 useEffect 依赖数组包含 innerOptions,但效果体中没有使用它,这可能导致不必要的重新渲染。

建议移除不必要的依赖项:

- }, [selectedValue, innerOptions, innerVisible])
+ }, [selectedValue, innerVisible])

191-214: 渲染逻辑重构

renderPickerElement 函数封装了渲染逻辑,代码组织更加清晰:

  1. 使用新的 PickerView 组件替代旧的 PickerPanel
  2. 属性传递和回调处理更加直接

但在第200行,直接使用 props.options 而非之前解构的 options (含默认值),可能导致不一致。

- options={props.options}
+ options={options}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between f81ef99 and f278479.

📒 Files selected for processing (1)
  • src/packages/picker/picker.taro.tsx (7 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (10)
src/packages/picker/picker.taro.tsx (10)

8-24: 导入模块的重构改进了组件架构

导入更改表明组件架构有显著改进:

  1. 从使用 PickerPanel 切换到 PickerView
  2. 引入更精确的类型定义如 PickerOptions, PickerValue
  3. 添加 isEqual 用于优化比较操作
  4. 引入 SafeArea 组件提升用户体验

这些变更使组件结构更清晰,类型定义更严格,有利于代码维护和类型安全。


29-36: Props 接口类型定义优化提升类型安全

接口定义的变更将通用数组类型替换为更具体的类型:

  • options: PickerOptions[] 替代旧的 (PickerOption | PickerOption[])[]
  • valuedefaultValue 使用 PickerValue[] 类型
  • 回调函数签名使用更明确的类型和参数结构,尤其是 onChange 使用了单一的 PickerOnChangeCallbackParameter 对象

这些改进有效增强了类型安全性,减少了潜在的类型错误,使 API 更加清晰。

Also applies to: 41-49


86-93: selectedValue 的处理方式改进

usePropsValue 钩子的使用和回调修改改进了值的处理流程:

  • 类型注解明确为 PickerValue[]
  • 回调中直接使用 selectedOptionsRef.current 传递给 onConfirm

这种方式与修改后的类型系统保持一致,但需确保 selectedOptionsRef 在初始渲染时已正确初始化。
[approve]


98-102: onClose 回调参数更新

闭包处理通过使用 selectedOptionsRef.currentinnerValue 作为回调参数,保持了与接口定义的一致性。这是一个好的改进,确保了组件关闭时能够传递正确的选中值。


115-119: 状态管理重构

状态管理的重构包括:

  1. 使用 useStateuseRef 跟踪 innerValue
  2. 类型明确的 innerOptions 状态
  3. 添加 selectedOptionsRef 引用持久化选中选项

这种方式更加稳健,可以在重渲染时保持一致性,尤其是针对回调函数的处理。


128-145: 变更处理逻辑优化

新的 onChangeItem 函数很好地封装了选项变更的处理逻辑:

  1. 维护 selectedOptionsRef 的当前状态
  2. 使用 isEqual 避免不必要的更新
  3. 更新 innerValueRef 和状态
  4. 条件性触发外部 onChange 回调

这种实现方式清晰明了,有效减少了冗余代码,同时优化了性能。


147-157: 确认和取消事件处理优化

onConfirmEventonCancelEvent 函数重构使逻辑更清晰:

  1. 确认事件中添加了移动检测,防止在滚动时意外确认
  2. 取消事件正确重置内部值到之前选中的值

这种实现改进了用户体验,避免了可能的错误操作。

Also applies to: 159-163


219-230: Popup 组件用法优化

Popup 处理的改进包括:

  1. 简化遮罩点击逻辑,直接调用 onCancelEvent
  2. 条件渲染提高性能,只在 innerVisible 为 true 时渲染内容
  3. 添加 SafeArea 组件改善移动设备体验

这些更改提升了组件的性能和用户体验。


235-235: 类型参数更新

React.forwardRef 中使用 PickerRef 替代 unknown 增强了类型安全性,使 ref 对象具有明确的类型定义,便于使用者了解可用的方法和属性。


8-236:

❓ Verification inconclusive

关于 PR 需求的验证

PR 评论中提到了 "Picker 弹出来没有动画",但当前代码中未明确解决此问题。Popup 组件应该提供动画效果,建议检查 Popup 组件的配置或考虑添加动画属性。

关于默认值选择的问题,当前实现以 selectedValue 初始化 innerValue,应该符合需求,但需确认没有默认值时的行为是否符合预期。

对于闰年日期选择器问题,本文件是 Picker 的基础实现,此问题可能需要在 DatePicker 组件中解决。


🌐 Web query:

React 组件中如何为弹出层添加动画效果的最佳实践

💡 Result:

在 React 组件中为弹出层添加动画效果时,最佳实践需要兼顾视觉效果与性能优化。以下是几种主流实现方案及核心要点:

一、CSS 过渡方案

通过 CSS transitiontransform 实现基础动画:

.modal {
  transition: transform 0.3s ease-out;
  transform: translateY(100%);
}
.modal.active {
  transform: translateY(0);
}

关键技巧

  • 使用 requestAnimationFrame 延迟激活状态确保 CSS 过渡生效[5]
  • 通过 opened 状态控制组件挂载时机[5]
const [opened, setOpened] = useState(false);
useEffect(() => {
  if (visible) {
    setOpened(true);
    requestAnimationFrame(() => setActive(true));
  }
}, [visible]);

二、React Animated API

适用于复杂时序控制的场景:

const fadeAnim = useRef(new Animated.Value(0)).current;
Animated.timing(fadeAnim, {
  toValue: 1,
  duration: 500,
  easing: Easing.bezier(0.4, 0, 0.2, 1),
}).start();

典型应用

  • Y轴位移动画结合插值计算[3]
translateY: offset.interpolate({
  inputRange: [0, 1],
  outputRange: [height, height - contentHeight]
})

三、第三方动画库(推荐)

react-spring 提供声明式动画方案:

const [maskStyle, contentStyle] = useSprings(2, [
  { opacity: visible ? 1 : 0 },
  { transform: `translateY(${visible ? '0%' : '100%'})` }
]);

优势特性

  • 自动处理生命周期与性能优化[7]
  • GPU加速的流畅动画效果[6]

四、关键优化策略

优化方向 实施方法
条件渲染 {isMounted && <Modal/>}
Portal挂载 createPortal(modalContent, document.body)
避免重渲染 React.memo() + shouldComponentUpdate
异步加载资源 const Modal = React.lazy(() => import('./Modal'))

五、进阶实践建议

  1. 复合动画控制:使用 Animated.parallel()/sequence()编排多元素协同运动[3]
  2. 无障碍支持:添加 role="dialog" + aria-modal="true" + ESC关闭支持[2][6]
  3. 弹性动效设计:采用弹簧物理模型替代线性缓动 (easing: Easing.bezier())[7]

通过合理选择技术方案并遵循这些实践原则,可在 React 应用中构建既流畅又稳定的弹层动效体系。[1][3][5][7]

Citations:


关于 Picker 弹层动画及默认值处理的建议

  • 目前在 Picker 弹层实现中未见明确的动画处理。建议检查 Popup 组件的配置,确认是否支持动画相关属性;如果没有,考虑采用 CSS 过渡、React Animated API 或 react-spring 等方案,为弹层添加平滑的过渡动画效果。
  • 默认值部分目前通过 selectedValue 初始化 innerValue,看上去符合预期,但请进一步确认当未提供默认值时组件的行为是否符合需求。
  • 关于闰年日期选择的问题,由于本文件实现的是基础 Picker 逻辑,相关逻辑应在 DatePicker 组件中处理,不在当前范围内。

@irisSong irisSong requested a review from xiaoyatong February 25, 2025 08:41
Copy link
Collaborator

@xiaoyatong xiaoyatong left a comment

Choose a reason for hiding this comment

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

picker 的 afterclose 方法,先暂时去掉,待有反馈再补充~

@xiaoyatong xiaoyatong merged commit 95dc4b8 into jdf2e:feat_v3.x Feb 27, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3.x Target branch 3.x action:review This PR needs more reviews (less than 2 approvals) size/XXL

Projects

None yet

3 participants