子组件应用Transition无效果,父组件应用则正常的问题
问题分析与解决方案
问题核心是内部定义的组件每次父组件重渲染时会被重新创建,导致DOM元素卸载重建,过渡动画失效。
你的代码里,InnerComponent定义在OuterComponent内部,当sidebarCtx.isOpen变化触发父组件重渲染时,InnerComponent会被重新定义为一个全新的组件类型,React会卸载旧的子组件DOM,再挂载新的,这就跳过了CSS过渡动画的触发条件(需要同一DOM元素的样式变化)。而把样式放在外层div时,外层DOM不会被重建,样式变化自然能触发过渡。
解决方案1:将子组件移到父组件外部
把InnerComponent移到OuterComponent外面,避免每次父组件重渲染都创建新组件:
import { useContext } from 'react'; import { SidebarContext } from './your-context-path'; const InnerComponent = ({ className, children }) => { return ( <div className={className}> {children} <a>testing</a> </div> ); }; export const OuterComponent = () => { const sidebarCtx = useContext(SidebarContext); const style = "w-[100px] h-[60px] transition-all duration-1000 bg-purple-900 text-2xl text-white " + (sidebarCtx.isOpen ? "w-[400px]" : ""); return ( <InnerComponent className={style} /> ); };
解决方案2:用useMemo缓存内部子组件
如果必须在父组件内部定义子组件,用useMemo缓存组件,确保只有依赖变化时才重新创建:
import { useContext, useMemo } from 'react'; import { SidebarContext } from './your-context-path'; export const OuterComponent = () => { const sidebarCtx = useContext(SidebarContext); const style = "w-[100px] h-[60px] transition-all duration-1000 bg-purple-900 text-2xl text-white " + (sidebarCtx.isOpen ? "w-[400px]" : ""); const InnerComponent = useMemo(() => { return ({ children }) => { return ( <div className={style}> {children} <a>testing</a> </div> ); }; }, [style]); // 依赖style,只有style变化时才重新创建组件 return ( <InnerComponent /> ); };
解决方案3:将样式作为props传入子组件
另一种方式是把style作为props传给子组件,而不是让子组件直接引用父组件的变量,同时确保子组件不被重复创建:
import { useContext } from 'react'; import { SidebarContext } from './your-context-path'; const InnerComponent = ({ style, children }) => { return ( <div className={style}> {children} <a>testing</a> </div> ); }; export const OuterComponent = () => { const sidebarCtx = useContext(SidebarContext); const style = "w-[100px] h-[60px] transition-all duration-1000 bg-purple-900 text-2xl text-white " + (sidebarCtx.isOpen ? "w-[400px]" : ""); return ( <InnerComponent style={style} /> ); };
以上三种方案都能避免子组件被重复创建,保证DOM元素的连续性,从而让Tailwind的过渡动画正常触发。
内容的提问来源于stack exchange,提问作者amir_70
相关产品推荐
相关产品推荐

