这是按钮的全部代码。我有涟漪效应的问题。当用户单击按钮时,组件将创建一个新的rippleElements
实体进行渲染。此时一切都很好。
动画结束后,将调用onAnimationEnd
。问题是,我在rippleElements
中没有最后添加的元素。为什么?元素已经渲染,动画结束了,但是状态没有更新?如您所见,我有2个console.log
。第一个在useEffect
中,它显示正确的值。但是onAnimationEnd
中的第二个具有错误的值,并且console.log
在第一个之后触发。这是怎么回事? :)
import { omit } from 'underscore';
import React, { FunctionComponent, ButtonHTMLAttributes, useState, useEffect } from 'react';
import uuid from 'uuid/v4';
import classnames from 'classnames';
export interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
primary: boolean,
ripple: boolean,
additionalClass?: string,
}
const Button: FunctionComponent<Props> = (props) => {
const [rippleElements, setRippleElements] = useState<JSX.Element[]>([]);
useEffect(() => {
// 1, actual - 1
console.log(rippleElements, rippleElements.length)
}, [rippleElements]);
const {primary, ripple, additionalClass, children} = props;
const classNames = classnames(
'btn',
{
primary
},
{
'with-ripple': ripple
},
additionalClass
);
function onAnimationEnd(key: string) {
console.log(rippleElements.length) // 0, actual - 1
// setRippleElements(rippleElements.filter(element => element.key !== key));
}
function newRippleElement(d: number, left: string, top: string) {
const key = uuid();
return (
<div
key={key}
className="ripple"
style={{width: d, height: d, left, top}}
onAnimationEnd={() => onAnimationEnd(key)}
>
</div>
);
}
function renderRippleElements() {
return rippleElements;
}
return (
<button
className={classNames}
{...omit(props, ['additionalClass', 'primary'])}
onClick={(event) => {
if (props.onClick) {
props.onClick(event);
}
if (ripple) {
var rect = event.currentTarget.getBoundingClientRect();
const d = Math.max(event.currentTarget.clientWidth, event.currentTarget.clientHeight);
const left = event.clientX - rect.left -d/2 + 'px';
const top = event.clientY - rect.top - d/2 + 'px';
const rippleElement = newRippleElement(d, left, top);
setRippleElements([...rippleElements, rippleElement]);
}
}}
>
{children}
{renderRippleElements()}
</button>
);
}
export default Button;