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: usecallback to fix render too many times, button,animatingnumbers,avatar,audio; and fix avatargroup when length > maxsize #2628

Merged
merged 4 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions src/packages/animatingnumbers/countup.taro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, {
CSSProperties,
FunctionComponent,
useEffect,
useCallback,
useRef,
useState,
} from 'react'
Expand Down Expand Up @@ -33,14 +34,14 @@ export const CountUp: FunctionComponent<Partial<CountUpProps>> = (props) => {
className,
thousands,
style,
...reset
...rest
} = mergeProps(defaultProps, props)
const classPrefix = 'nut-countup'
const countupRef = useRef<HTMLDivElement>(null)
const timerRef = useRef(0)
const numbers = Array.from({ length: 10 }, (v, i) => i)

const getShowNumber = () => {
const getShowNumber = useCallback(() => {
const splitArr = value.split('.')
const intNumber =
length && splitArr[0].length < length
Expand All @@ -50,16 +51,15 @@ export const CountUp: FunctionComponent<Partial<CountUpProps>> = (props) => {
thousands ? intNumber.replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') : intNumber
}${splitArr[1] ? '.' : ''}${splitArr[1] || ''}`
return currNumber.split('')
}
}, [length, thousands, value])

const [numerArr, setNumerArr] = useState<string[]>([])

const [transformArr, setTransformArr] = useState<Array<string>>([])
const isLoaded = useRef(false)

const setNumberTransform = () => {
const setNumberTransform = useCallback(() => {
if (countupRef.current && numerArr.length) {
const query = createSelectorQuery()
createSelectorQuery()
.selectAll('.nut-countup-listitem')
.node((numberItems: any) => {
const transformArrCache: string[] = []
Expand All @@ -79,7 +79,7 @@ export const CountUp: FunctionComponent<Partial<CountUpProps>> = (props) => {
})
.exec()
}
}
}, [numerArr])

const numberEaseStyle = (idx: number) => {
return {
Expand All @@ -90,7 +90,7 @@ export const CountUp: FunctionComponent<Partial<CountUpProps>> = (props) => {

useEffect(() => {
setNumberTransform()
}, [numerArr])
}, [numerArr, setNumberTransform])

useEffect(() => {
if (!isLoaded.current) {
Expand All @@ -104,7 +104,7 @@ export const CountUp: FunctionComponent<Partial<CountUpProps>> = (props) => {
return () => {
window.clearTimeout(timerRef.current)
}
}, [value])
}, [value, delay, getShowNumber])

return (
<div className={`${classPrefix} ${className}`} ref={countupRef}>
Expand Down
9 changes: 5 additions & 4 deletions src/packages/animatingnumbers/countup.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, {
CSSProperties,
FunctionComponent,
useCallback,
useEffect,
useMemo,
useRef,
Expand Down Expand Up @@ -32,7 +33,7 @@ export const CountUp: FunctionComponent<Partial<CountUpProps>> = (props) => {
className,
thousands,
style,
...reset
...rest
} = mergeProps(defaultProps, props)
const classPrefix = 'nut-countup'
const countupRef = useRef<HTMLDivElement>(null)
Expand All @@ -53,7 +54,7 @@ export const CountUp: FunctionComponent<Partial<CountUpProps>> = (props) => {

const numerArr = useMemo(getShowNumber, [value, length, thousands])

const setNumberTransform = () => {
const setNumberTransform = useCallback(() => {
if (countupRef.current) {
const numberItems = countupRef.current.querySelectorAll(
'.nut-countup-number'
Expand All @@ -72,7 +73,7 @@ export const CountUp: FunctionComponent<Partial<CountUpProps>> = (props) => {
}
})
}
}
}, [numerArr])

const numberEaseStyle: CSSProperties = {
transition: `transform ${duration}s ease-in-out`,
Expand All @@ -85,7 +86,7 @@ export const CountUp: FunctionComponent<Partial<CountUpProps>> = (props) => {
return () => {
window.clearTimeout(timerRef.current)
}
}, [numerArr])
}, [numerArr, delay, setNumberTransform])

return (
<div className={`${classPrefix} ${className}`} ref={countupRef}>
Expand Down
2 changes: 1 addition & 1 deletion src/packages/animatingnumbers/demos/h5/demo2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const Demo2 = () => {
Math.random() * 89 + 10
)}`
)
}, 30000)
}, 3000)
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

考虑间隔时间的影响

将间隔时间从30秒减少到3秒可能会对用户体验和性能产生以下影响:

  1. 更频繁的状态更新可能会导致更多的重渲染,可能影响性能。
  2. 数字变化太快可能会使用户难以阅读或理解显示的值。
  3. 更频繁的更新可能会增加设备的电池消耗。

建议:

  • 考虑使用 useCallback 来优化 setEndNumer 函数。
  • 可以添加一个配置选项,允许用户或开发者自定义更新间隔。
  • 考虑使用 requestAnimationFrame 代替 setInterval 以获得更好的性能。

您是否需要我为这些建议提供具体的代码实现?

}, [])
return (
<Cell
Expand Down
2 changes: 1 addition & 1 deletion src/packages/animatingnumbers/demos/taro/demo2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const Demo2 = () => {
Math.random() * 89 + 10
)}`
)
}, 30000)
}, 3000)
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

考虑间隔时间的影响

将更新间隔从30秒减少到3秒可能会对性能和用户体验产生影响。

  1. 性能考虑:更频繁的更新可能会增加设备的电池消耗。
  2. 用户体验:快速变化的数字可能会分散用户的注意力。

建议:

  • 考虑使用一个可配置的间隔时间,以便在不同场景下灵活调整。
  • 添加注释解释为什么选择3秒作为间隔时间。

您是否考虑过使用一个常量或配置变量来定义这个间隔时间?例如:

const UPDATE_INTERVAL = 3000; // milliseconds

useEffect(() => {
  setInterval(() => {
    // ... existing code ...
  }, UPDATE_INTERVAL);
}, []);

这样可以提高代码的可维护性和灵活性。

}, [])
return (
<Cell
Expand Down
6 changes: 2 additions & 4 deletions src/packages/audio/audio.taro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,13 @@ export const Audio: FunctionComponent<
onPlayEnd?.(audioCtx)
}
})

audioCtx.onPlay(() => {
const { duration } = audioCtx
setTotalSeconds(Math.floor(duration))
onPlay?.(audioCtx)
})
audioCtx.onCanplay(() => {
const intervalID = setInterval(function () {
const intervalID = setInterval(() => {
if (audioCtx.duration !== 0) {
setTotalSeconds(audioCtx.duration)
clearInterval(intervalID)
Expand All @@ -122,8 +121,7 @@ export const Audio: FunctionComponent<
})

audioCtx.onError((res) => {
console.warn('code', res.errCode)
console.warn('message', res.errMsg)
console.warn('onError', res.errCode, res.errMsg)
})

function formatSeconds(value: string) {
Expand Down
97 changes: 48 additions & 49 deletions src/packages/avatar/avatar.taro.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import React, {
useRef,
FunctionComponent,
useContext,
useCallback,
} from 'react'
import type { MouseEvent } from 'react'
import Taro, { getEnv } from '@tarojs/taro'
import classNames from 'classnames'
import { User } from '@nutui/icons-react-taro'
import Image from '@/packages/image/index.taro'
import { AvatarContext } from '@/packages/avatargroup/context'
import Image from '@/packages/image/index.taro'
import { BasicComponent, ComponentDefaults } from '@/utils/typings'
import AvatarGroup from '@/packages/avatargroup/index.taro'

Expand All @@ -34,9 +35,9 @@ const defaultProps = {
size: '',
shape: 'round',
icon: '',
fit: 'cover',
background: '#eee',
color: '#666',
fit: 'cover',
src: '',
alt: '',
} as AvatarProps
Expand All @@ -52,9 +53,9 @@ export const Avatar: FunctionComponent<
background,
color,
src,
alt,
icon,
fit,
alt,
className,
style,
onClick,
Expand All @@ -67,14 +68,15 @@ export const Avatar: FunctionComponent<

const [maxSum, setMaxSum] = useState(0) // avatarGroup里的avatar的个数
const [showMax, setShowMax] = useState(false) // 是否显示的最大头像个数
const [avatarIndex, setAvatarIndex] = useState(1) // avatar的索引
const [avatarIndex, setAvatarIndex] = useState(1)
const avatarRef = useRef<any>(null)
const parent: any = useContext(AvatarContext)
const sizeValue = ['large', 'normal', 'small']
const { propAvatarGroup, avatarGroupRef } = parent

const classes = classNames({
[`nut-avatar-${parent?.propAvatarGroup?.size || size || 'normal'}`]: true,
[`nut-avatar-${parent?.propAvatarGroup?.shape || shape}`]: true,
[`nut-avatar-${propAvatarGroup?.size || size || 'normal'}`]: true,
[`nut-avatar-${propAvatarGroup?.shape || shape}`]: true,
})
const cls = classNames(classPrefix, classes, className)

Expand All @@ -84,27 +86,53 @@ export const Avatar: FunctionComponent<
backgroundColor: `${background}`,
color,
marginLeft:
avatarIndex !== 1 && parent?.propAvatarGroup?.gap
? `${parent?.propAvatarGroup?.gap}px`
avatarIndex !== 1 && propAvatarGroup?.gap
? `${propAvatarGroup?.gap}px`
: '',
zIndex:
parent?.propAvatarGroup?.level === 'right'
propAvatarGroup?.level === 'right'
? `${Math.abs(maxSum - avatarIndex)}`
: '',
...style,
}

const maxStyles: React.CSSProperties = {
backgroundColor: `${parent?.propAvatarGroup?.maxBackground}`,
color: `${parent?.propAvatarGroup?.maxColor}`,
backgroundColor: `${propAvatarGroup?.maxBackground}`,
color: `${propAvatarGroup?.maxColor}`,
}

const avatarLength = useCallback(
(children: any) => {
for (let i = 0; i < children.length; i++) {
if (
children[i] &&
children[i].classList &&
isAvatarInClassList(children[i])
) {
children[i].setAttribute('data-index', i + 1)
}
}
const index = Number(avatarRef?.current?.dataset?.index)
const maxCount = propAvatarGroup?.max
setMaxSum(children.length)
setAvatarIndex(index)
if (
index === children.length &&
index !== maxCount &&
children.length > maxCount
) {
setShowMax(true)
}
},
[propAvatarGroup?.max]
)

useEffect(() => {
const avatarChildren = parent?.avatarGroupRef?.current.children
const avatarChildren = avatarGroupRef?.current.children
if (avatarChildren) {
avatarLength(avatarChildren)
}
}, [])
}, [avatarLength, avatarGroupRef])

const isAvatarInClassList = (element: any) => {
if (getEnv() === Taro.ENV_TYPE.WEB) {
Expand All @@ -120,33 +148,8 @@ export const Avatar: FunctionComponent<
)
}

const avatarLength = (children: any) => {
for (let i = 0; i < children.length; i++) {
if (
children[i] &&
children[i].classList &&
isAvatarInClassList(children[i])
) {
children[i].setAttribute('data-index', i + 1)
}
}
const index = avatarRef?.current?.dataset?.index
const maxCount = parent?.propAvatarGroup?.max
setMaxSum(children.length)
setAvatarIndex(index)
if (
index === children.length &&
index !== maxCount &&
children.length > maxCount
) {
setShowMax(true)
}
}

const errorEvent = () => {
if (onError) {
onError()
}
onError && onError()
}

const clickAvatar = (e: MouseEvent<HTMLDivElement>) => {
Expand All @@ -156,17 +159,16 @@ export const Avatar: FunctionComponent<
return (
<>
{(showMax ||
!parent?.propAvatarGroup?.max ||
avatarIndex <= parent?.propAvatarGroup?.max) && (
!propAvatarGroup?.max ||
avatarIndex <= propAvatarGroup?.max) && (
<div
className={cls}
{...rest}
style={!showMax ? styles : maxStyles}
onClick={clickAvatar}
ref={avatarRef}
>
{(!parent?.propAvatarGroup?.max ||
avatarIndex <= parent?.propAvatarGroup?.max) && (
{(!propAvatarGroup?.max || avatarIndex <= propAvatarGroup?.max) && (
<>
{src && (
<Image
Expand All @@ -186,14 +188,11 @@ export const Avatar: FunctionComponent<
{!src && !icon && !children && <User className="icon" />}
</>
)}
{/* 折叠头像 */}
{showMax && (
<div className="text">
{parent?.propAvatarGroup?.maxContent
? parent?.propAvatarGroup?.maxContent
: `+ ${
avatarIndex - Number(parent?.propAvatarGroup?.max || 0)
}`}
{propAvatarGroup?.maxContent
? propAvatarGroup?.maxContent
: `+ ${avatarIndex - Number(propAvatarGroup?.max || 0)}`}
</div>
)}
</div>
Expand Down
Loading
Loading