React CSS Transition Group

2019-08-20 08:39发布

问题:

Can someone help me with slide up/down transition that I am trying to create for a fullscreen popup. I am unable to get the desired ease in slide up effect using CSSTransitionGroup. The code example can be found here

Any help would be much appreciated. Thanks

回答1:

Theres a few issues at play here, all easy to fix:

1) You must use import CSSTransitionGroup from 'react-addons-css-transition-group rather than just the plain old transition group package - that only adds lifecycle hooks, which the CSS version uses to add/remove classes

2) The most important thing to understand is what actually triggers an animation. CSS transition groups works by applying transition classes to child elements that are entering and exiting its children (kept track of by a key), but in order to do so the CSSTransitionGroup must exist already, it is the children that conditionally exist or not. In your code, by only adding the CSSTransition group itself when the popup state is open, means that it cannot monitor its children so it all just appears and dissappears with no transition. Therefore you must make CSSTransition group always be rendered, but then conditionally add the popup div as a child when the state is open...

const PopUp = ({ state, close }) => {

  return (
      <CSSTransitionGroup
            transitionName="pop"
            transitionAppear={true}
            transitionAppearTimeout={2000}
            transitionEnterTimeout={2000}
            transitionLeaveTimeout={300}
            component="div"
            >
           {state.open && <div key="popup"
              style={{
                width: window.innerWidth,
                position: 'fixed',
                left: 0,
                top: 0,
                overflowX: 'hidden',
                backgroundColor: 'white',
                zIndex: '999',
              }}
            >
              <span>I am a popup</span>
              <FlatButton label="Close" onClick={close} />
            </div>
           }
      </CSSTransitionGroup>
  );
};

3) You can see from the above I have also added the appear in case the animation is to happen on first mount - in your case its fine as has already rendered in the closed state first but worth noting here for future reference

4) Finally you are animating on the height property in CSS, but you have set the height explicitly to height: window.innerHeight in your style property. This will translate to the style tag in HTML, which always takes precedence over any CSS stylesheet rules, so your animated height always loses out to it. Remove that and your animation works - however the height will not be set after the animation ends. You can fix this by keeping your height: window.innerHeight and forcing the CSS defined heights to override it with the height: 100vh !important; syntax (although this is in fact bad CSS practice as causes its own headaches when you create more complex stylesheets, as it stops you being able to use specificity)

Here is a working version: https://codesandbox.io/s/W7Q8QP56W

For further improvement on this I suggest you either move all your CSS for this component to a stylesheet so they can work overriding each other as normal using specificity and the cascade, or use something like opacity to animate on instead (as the default default is 1 you wont need to set it in your JS style prop) - react will remove the element entirely once the animation is done anyway, so you wont be blocked interacting with the page when its closed so you are free to hard code it to the full page height



回答2:

I could achieve the same with react-motion. Example: