Tengo un componente Basket que necesita alternar un componente BasketContents cuando se hace clic en él. Esto funciona:
constructor() { super(); this.state = { open: false } this.handleDropDown = this.handleDropDown.bind(this); } handleDropDown() { this.setState({ open: !this.state.open }) } render() { return( <div className="basket"> <button className="basketBtn" onClick={this.handleDropDown}> Open </button> { this.state.open ? <BasketContents /> : null } </div> ) } Utiliza un condicional para mostrar o no el componente BasketContents . Ahora quiero que se desvanezca. Intenté agregar un gancho ComponentDidMount a BasketContents para cambiar la opacidad, pero eso no funciona. ¿Hay una manera simple de hacer esto?
Un ejemplo usando alternancia de clase CSS + transiciones de opacidad:
https://jsfiddle.net/ybktodLc/
Aquí está el CSS interesante:
.basket { transition: opacity 0.5s; opacity: 1; } .basket.hide { opacity: 0; pointer-events:none; }Y la función de renderizado:
render() { const classes = this.state.open ? 'basket' : 'basket hide' return( <div className="basket"> <button className="basketBtn" onClick={this.handleDropDown}> {this.state.open ? 'Close' : 'Open'} </button> <BasketContents className={classes}/> </div> ) }Yo usaría react-motion así:
<Motion style={{currentOpacity: spring(this.state.open ? 1 : 0, { stiffness: 140, damping: 20 })}}> {({currentOpacity}) => <div style={{opacity: currentOpacity}}> <BasketContents /> </div> } </Motion>No lo he probado, pero debería funcionar.
Estaba haciendo esto para un botón de hamburguesa de menú móvil para expandir y cerrar la navegación. Quería seguir renderizando el contenido, pero solo quiero una transición suave cada vez que abro/cierro el menú. Esta es mi solución. En compontentDidMount() y en cada menú, haga clic en el botón de hamburguesa y haga clic en el botón de cerrar, configuro la opacidad en 0 y espero 1 milisegundo en setTimeout antes de agregar la transición:
handleMenuExpand = () => { this.handleTransition(false); } handleMenuShrink = () => { this.handleTransition(true); } handleTransition = (isHidden) => { this.setState({ transitionStyle: { opacity: '0' }, isNavHidden: isHidden }); setTimeout(() => this.setState({ transitionStyle: { transition: 'opacity 0.8s', opacity: '1' } }), 1 ); } componentDidMount() { this.handleTransition(this._isMobile); } return( <nav className="navbar-container" style={this.state.transitionStyle}> { (this.state.isNavHidden) ? <ul className="navbar-content"> <li className="menu-expand-container" style={topBarStyle} > <img src={MenuHamburgerPic} style={menuButtonStyle} alt="Menu Pic" onClick={this.handleMenuExpand} /> </li> </ul> : <ul className="navbar-content"> {(this._isMobile) && <li style={closeButtonContainerStyle} > <img src={MenuClosePic} style={closeMenuButtonStyle} alt="Menu Pic" onClick={this.handleMenuShrink} /> </li> } <li>NAV ELEMENT 1</li> <li>AOTHER NAV ELEMENT</li> </ul> } </nav> );