我有一个列表(ParentBox.tsx
),其中包含许多项(Box.tsx
)。单击 * 添加 * 按钮时,ParentBox
会多一个唯一的Box
。动画效果很好。但是,在两种情况下效果不好:
1.当我点击Box
时,它会从列表中删除该项目。Framer Motion会在没有退出动画的情况下从用户界面中删除Box
。
1.当单击“全部删除”时,将删除整个项目列表。没有退出交错效果。
我想有一个单独的元素的列表动画了,当整个列表被清除,有他们一个接一个动画了。
CodeSanbox中的完整重现
父框
const variantsBoxContainer: Variants = {
hidden: {
transition: {
staggerChildren: 0.1,
delayChildren: 0.3,
staggerDirection: -1
}
},
show: {
transition: {
staggerChildren: 0.1,
delayChildren: 0.3,
staggerDirection: 1
}
}
};
let id = 3;
export const ParentBox = (props: ParentBoxProps) => {
const [items, setItems] = useState<Item[]>([
{ id: 1, text: "Test #1" },
{ id: 2, text: "Test #2" }
]);
return (
<motion.div
className="parentbox"
>
<button
onClick={() => {
id++;
setItems([...items, { id: id, text: `Click to delete id ${id}` }]);
}}
>
Add
</button>
<button
onClick={() => {
id++;
setItems([]);
}}
>
Remove All
</button>
<motion.ol
variants={variantsBoxContainer}
initial="hidden"
animate="show"
exit="hidden"
>
<AnimatePresence mode="popLayout">
{items
.sort((a, b) => a.id - b.id)
.map((d) => (
<Box
key={d.id}
data={d}
onRemove={(item) => {
const newList = items.filter((i) => i.id !== item.id);
console.log(newList);
setItems(newList);
}}
/>
))}
</AnimatePresence>
</motion.ol>
</motion.div>
);
};
Package 盒
const variantBox: Variants = {
hidden: { opacity: 0, top: -100, transition: { duration: 2 } },
show: { opacity: 1, top: 0, transition: { duration: 2 } }
};
export const Box = (props: BoxProps) => {
return (
<motion.li
className="box"
variants={variantBox}
onClick={() => {
props.onRemove(props.data);
}}
>
{props.data.text}
</motion.li>
);
};
到目前为止,我已经尝试过:
1.在Box
组件上添加/删除对initial
、animate
、exit
的明确提及。
1.添加/删除when
选项。
1.已尝试AnimatedPresence
中的所有mode
1.尝试为hidden
(exit)变量添加一个函数,以便为每个索引自定义延迟
1.确保所有Box
都具有唯一的key
让我知道,如果你有任何想法,我错过了什么有动画的Box
删除(儿童)。
CodeSanbox
1条答案
按热度按时间ee7vknir1#
如果您明确指示要为动画状态使用的变体,则退出动画将起作用:
我认为
AnimatePresence
与staggerChildren
属性冲突,因为它出现在父级和子级之间。请在GitHub上查看此问题。最快的解决方法可能是使用动态变量,并在
Box
组件的变量中手动设置delay
(基于items
数组中的索引)。