react 中自动调整组件尺寸的动画优化
在 react 中创建一个根据文本量自动调整尺寸的组件可能会遇到动画闪烁的问题。以下是优化该动画的一种方法:
实现中,文本长度变化时计算新的 scale 值,但在 useeffect 钩子中触发渲染。这会导致动画闪烁,因为组件在计算 scale 值之前已渲染。
为了解决这个问题,可以使用 uselayouteffect 钩子。uselayouteffect 在浏览器布局更新后运行,允许在渲染前计算 scale 值,从而消除动画闪烁。
修改后的代码如下:
import { useState, useEffect, useRef, FC } from 'react'; const AutoScalingText: FC<{ text: string }> = ({ text }) => { const [scale, setScale] = useState(1); const nodeRef = useRef<HTMLDivElement>(null); const parentNodeOffsetWidth = useRef<number>(0); //全局变量,免得每次都重新计算parentNodeOffsetWidth useEffect(() => { parentNodeOffsetWidth.current = ( nodeRef.current!.parentNode as HTMLElement ).offsetWidth; }, []); useLayoutEffect(() => { const node = nodeRef.current; if (!node) return; // 每次text变化时,根据文本长度设定scale 范围 const availableWidth = parentNodeOffsetWidth.current - 32; const actualWidth = node.offsetWidth; const actualScale = availableWidth / actualWidth; if (scale !== actualScale) { if (actualScale < 1) { setScale(actualScale); } else if (scale < 1) { setScale(1); } } }, [text]); return ( <div className='auto-scaling-text' style={{ transform: `scale(${scale},${scale})` }} ref={nodeRef} > {text} </div> ); }; export default AutoScalingText;
通过使用 uselayouteffect 钩子,可以有效减少动画闪烁,从而改善组件的用户体验。