1
votes

I am writing a react app that acts a wizard to guide the user through inputting information for a form. The App has a header part which states which step the user is on and a content section which renders a component based on the current step. I am using styled components and the only thing I am looking to do for now is have it so when a component switches (the current step state changes) the new component fades in instead of just popping up.

I am completely new to animations in react and a lot of the tutorials I have been seeing only animate a certain element on the screen and not component transitions on render. I am using React-Spring animation library and trying to figure out how I should go about doing what I need. I am open to switching animation libraries if there is a easier one to use.

This is my App Component


import { Transition } from 'react-spring/renderprops'
... // other imports 

export default class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      currentStep: 1,
      modelChosen: '',
      aqlQuery: ''
    }
    this.navigateForward = this.navigateForward.bind(this)
    this.navigateBack = this.navigateBack.bind(this)
  }

... //navigation functions..

render() {
    let show = true
    return (
      <StyledApp>
        <Content>
          <Header
            step={this.state.currentStep}
            navigateBack={this.navigateBack}
          />
          <Transition
            native
            reset
            items={show}
            unique
            from={{ opacity: 0, transform: 'translate3d(100%,0,0)' }}
            enter={{ opacity: 1, transform: 'translate3d(0%,0,0)' }}
            leave={{ opacity: 0, transform: 'translate3d(-50%,0,0)' }}
          >
            {show =>
              show &&
              (props => (
                <div styles={props}>
                  <ModelStep
                    currentStep={this.state.currentStep}
                    navigateForward={this.navigateForward}
                  />
                  <QueryStep currentStep={this.state.currentStep} />
                </div>
              ))
            }
          </Transition>
        </Content>
      </StyledApp>
    )
  }
}

The ModelStep and QueryStep components render only when its their respective step.

For example this is my QueryStep component:

import { animated } from 'react-spring/renderprops'
..// other imports
export default class QueryStep extends Component {
  render() {
    if (this.props.currentStep !== 2) {
      return null
    }
    return <StyledQuery />
  }
}

const StyledQuery = styled(animated.div)`
  width: 1250px;
  background-color: ${colors.backgroundLight};
  height: 320px;

What I expected was that when the ModelStep navigates forward and thus changes the apps currentStep state, the QueryStep would fade in, however instead it just switches to it normally without any animation.

For reference I am trying to follow the simple page transitions example they have on the react-springs site.

1

1 Answers

0
votes

Transition is mounting a new elements then doing their enter animation while unmounting any old elements after doing their leave animations. So when you want to use more than two element in your trasition you have to leave the mounting and unmounting to the transition (no show && inside transition). Second make sure that you define the key property right, because transition will use the key property to decide which is new or old element (default key is item => item). Third, you have to use absolute position for the pages, because they are kind of overlapped when one is entering the other is leaving. Something like this:

      <Transition
        native
        reset
        items={this.state.currentStep}
        unique
        from={{ opacity: 0, transform: 'translate3d(100%,0,0)' }}
        enter={{ opacity: 1, transform: 'translate3d(0%,0,0)' }}
        leave={{ opacity: 0, transform: 'translate3d(-50%,0,0)' }}
      >
        {currStep =>
           (props => (
            <div styles={props}>
              <ModelStep
                currentStep={currStep}
                navigateForward={this.navigateForward}
              />
              <QueryStep currentStep={currStep} />
            </div>
          ))
        }
      </Transition>

I leave the positioning to you.