Skip to content

Commit

Permalink
perf(components/transition-group): 移除原来添加到 html 元素上的 data-key 标识
Browse files Browse the repository at this point in the history
  • Loading branch information
mengxinssfd committed Jul 30, 2023
1 parent d682b67 commit 96f6e26
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const TransitionGroup: React.FC<TransitionGroupProps> = (props) => {

const childMap = useChildMap(children, name);
const [wrapper, parentRef] = useWrapper(childMap, rest);
useFlips(parentRef, name);
useFlips(parentRef, childMap, name);
return wrapper;
};

Expand Down
7 changes: 4 additions & 3 deletions packages/components/src/transition-group/useChildMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ export function useChildMap(children: React.ReactNode, name: string) {
const onLeaved = (key: React.Key) => {
// leave 可能会丢失
setChildMap((prevChildren) => {
prevChildren.delete(key);
return new Map(prevChildren.entries());
const map = new Map(prevChildren);
map.delete(key);
return map;
});
};

Expand Down Expand Up @@ -138,7 +139,7 @@ function cloneTransition(
transition: React.ReactElement,
props: Partial<TransitionProps>,
) {
const _props = { ...props, 'data-key': transition.key } as TransitionProps;
const _props = { ...props } as TransitionProps;
const nextOn = props.on;
if (nextOn) {
const prevOn = transition.props.on as TransitionProps['on'];
Expand Down
33 changes: 19 additions & 14 deletions packages/components/src/transition-group/useFlips.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import React, { useLayoutEffect } from 'react';
import React, { useLayoutEffect, useRef } from 'react';
import { applyTranslation } from './transition-group.utils';
import type { ChildMap } from './transition-group.types';

export function useFlips(
wrapperRef: React.MutableRefObject<HTMLElement | undefined>,
childMap: ChildMap,
name: string,
) {
const prevRects = getChildRects(wrapperRef.current);
const prevChildMapRef = useRef(childMap);
const prevRects = getChildRects(wrapperRef.current, prevChildMapRef.current);
prevChildMapRef.current = childMap;

useLayoutEffect(() => {
const wrapperEl = wrapperRef.current;
if (!wrapperEl || !prevRects) return;

const moveClass = `${name}-move-active`;
const { children } = wrapperEl;
const nextRects: Record<string, DOMRect> = {};
const nextRects: Record<React.Key, DOMRect> = {};
// 获取最新的样式
forEachEl(children, (el, key) => {
forEachEl(children, childMap, (el, key) => {
el.style.transition = 'none';
nextRects[key] = el.getBoundingClientRect();
if (!prevRects[key]) prevRects[key] = nextRects[key]!;
Expand All @@ -24,7 +28,7 @@ export function useFlips(

const flips: Array<() => void> = [];
// 计算之前样式与现在的样式的差,并设置样式
forEachEl(children, (el, key) => {
forEachEl(children, childMap, (el, key) => {
// if (hasTransition(el, name)) return;
if (!applyTranslation(el, prevRects[key]!, nextRects[key]!)) return;
flips.push(() => {
Expand All @@ -47,28 +51,29 @@ export function useFlips(

function getChildRects(
wrapperEl: HTMLElement | undefined,
childMap: ChildMap,
): Record<React.Key, DOMRect> | void {
if (!wrapperEl) return;
const rects: Record<React.Key, DOMRect> = Object.create(null);
forEachEl(
wrapperEl.children,
childMap,
(el, key) => (rects[key] = el.getBoundingClientRect()),
);
return rects;
}

function forEachEl(
els: HTMLElement[] | NodeListOf<HTMLElement> | HTMLCollection,
cb: (el: HTMLElement, key: string) => void,
childMap: ChildMap,
cb: (el: HTMLElement, key: React.Key) => void,
) {
const len = els.length;
for (let i = 0; i < len; i++) {
const el = els[i] as HTMLElement | undefined;
if (!el) continue;
const key = el.getAttribute('data-key');
if (!key) continue;
cb(el, key);
}
let i = 0;
childMap.forEach((_, key) => {
const el = els[i++];
if (!el) return;
cb(el as HTMLElement, key);
});
}

// function hasTransition(el: HTMLElement, name: string): boolean {
Expand Down

0 comments on commit 96f6e26

Please sign in to comment.