React 自動(dòng)縮放組件動(dòng)畫閃爍問題及 useLayoutEffect 解決方法
在 React 開發(fā)中,動(dòng)態(tài)調(diào)整組件大小以適應(yīng)內(nèi)容的情況很常見。本文將解決一個(gè)基于文本長(zhǎng)度自動(dòng)縮放的 React 組件動(dòng)畫閃爍問題。
原代碼使用 useEffect hook 根據(jù)文本變化調(diào)整縮放比例。然而,useEffect 異步執(zhí)行,導(dǎo)致縮放動(dòng)畫過程中,組件可能先渲染未縮放狀態(tài),再縮放,造成閃爍。
問題代碼示例:
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); useEffect(() => { parentNodeOffsetWidth.current = (nodeRef.current!.parentNode as HTMLElement).offsetWidth; }, []); useEffect(() => { const node = nodeRef.current; if (!node) return; const availableWidth = parentNodeOffsetWidth.current - 32; const actualWidth = node.offsetWidth; const actualScale = availableWidth / actualWidth; if (scale !== actualScale) { // ...縮放邏輯... } }, [text]); return ( <div ref={nodeRef} style={{ transform: `scale(${scale})` }}> {text} </div> ); }; export default AutoScalingText;
解決方案:使用 useLayoutEffect
useLayoutEffect 與 useEffect 類似,但在瀏覽器布局和繪制階段之后同步執(zhí)行。這確保縮放比例計(jì)算完成后再進(jìn)行縮放,避免閃爍。
修改后的代碼:
useLayoutEffect(() => { const node = nodeRef.current; if (!node) return; const availableWidth = parentNodeOffsetWidth.current - 32; const actualWidth = node.offsetWidth; const actualScale = availableWidth / actualWidth; if (scale !== actualScale) { // ...縮放邏輯... } }, [text]);
通過將 useEffect 替換為 useLayoutEffect,可以有效消除或減少自動(dòng)縮放組件的動(dòng)畫閃爍,使動(dòng)畫更流暢自然。 注意,parentNodeOffsetWidth 的獲取應(yīng)在組件掛載后完成,避免獲取錯(cuò)誤值。
使用 useLayoutEffect 有效解決了 React 自動(dòng)縮放組件動(dòng)畫閃爍的問題,確保動(dòng)畫平滑過渡。
? 版權(quán)聲明
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載。
THE END