Array.map()或条件渲染的React组件Framer Motion退出转场不触发问题
问题原因
AnimatePresence仅对其直接子节点的卸载动作生效,你当前将固定key的<table>作为AnimatePresence的唯一直接子节点,无论内部列表如何更新,<table>本身永远不会被卸载,因此列表项的删除动作无法被AnimatePresence捕获,自然不会触发退场动画。- 新增元素时入场动画正常是因为入场动画不需要依赖
AnimatePresence,只要组件挂载时带initial和animate属性即可触发,这也是你之前用concat新增元素效果正常的原因。
修复方法
- 把
AnimatePresence移动到列表项的父级位置,直接包裹所有动态渲染的ListItem,同时确保每个ListItem是framer-motion导出的motion组件,且已配置exit属性 - 修改后的代码结构参考:
const data = [ { title: "Item 1", Description: "First item", id: 1 }, { title: "Item 2", Description: "Second item", id: 2 }, { title: "Item 3", Description: "Third item", id: 3 }, { title: "Item 4", Description: "Fourth item", id: 4 }, { title: "Item 5", Description: "Fifth item", id: 5 } ]; export default function App() { const [arrayItems, setArrayItems] = React.useState(data); const handleClick = (item) => { setArrayItems(arrayItems.filter((element) => element.id === item.id)); }; React.useEffect(() => { setArrayItems(data); }, []); return ( <div className="App"> <table style={{ borderCollapse: "collapse" }} key="1"> {/* AnimatePresence直接包裹动态列表项,不会生成额外DOM节点 */} <AnimatePresence> {arrayItems.map((item) => ( <ListItem handleClick={handleClick} item={item} key={item.id} /> ))} </AnimatePresence> </table> </div> ); }
- 你提到的
&&/三元运算符条件渲染触发不了退场动画的问题也是同理:需要把条件渲染的组件直接作为AnimatePresence的直接子节点,不要在外面套一层固定不会卸载的父容器再把AnimatePresence放在父容器外面。
内容的提问来源于stack exchange,提问作者Carlton Lindsay
相关产品推荐
相关产品推荐

