Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactJS: Fade in div and fade out div based on state

Tags:

reactjs

So, I am trying to fade in and fade out a set of inputs based on what button the user clicks. I tried using jQuery, but, the div was fading in and fading out at the same speed...

I am using es6 classes and react.

What I want is the user to press a button and the inputs fadeIn. Another button, the inputs fadeOut. I don't mind using jQuery, but I would like to understand how to do this with react.

renderInputs() {
  if (this.state.addType === "image") {
    return (
      <div className="addContainer">
        <input type="text" className="form-control" />
      </div>
    )
  } else {
    return (
     other inputs
    )
  }
}

render() {
  return (
    <CSSTransitionGroup
      transitionName="fadeInput"
      transitionEnterTimeout={500}
      transitionLeaveTimeout={300}>

      {this.renderInputs()} // this doesn't work but I want this content to be conditional.

    </CSSTransitionGroup>
  )
}

// SCSS
.fadeInput-enter {
  opacity: 0.01;
}

.fadeInput-enter.fadeInput-enter-active {
  opacity: 1;
  transition: opacity 500ms ease-in;
}

.fadeInput-leave {
  opacity: 1;
}

.fadeInput-leave.fadeInput-leave-active {
  opacity: 0.01;
  transition: opacity 300ms ease-in;
}
like image 439
Daltron Avatar asked Apr 30 '17 02:04

Daltron


3 Answers

Just use a conditional class and CSS.

Have a state variable like visible.

this.state = {
   visible:false
}

And for the other inputs do something like

<input className={this.state.visible?'fadeIn':'fadeOut'} />

So depending upon the state.visible the input will have a class of either fadeIn or fadeOut.

And then just use simple CSS

.fadeOut{
     opacity:0;
     width:0;
     height:0;
     transition: width 0.5s 0.5s, height 0.5s 0.5s, opacity 0.5s;

}
.fadeIn{
     opacity:1;
     width:100px;
     height:100px;
     transition: width 0.5s, height 0.5s, opacity 0.5s 0.5s;

}

So every time the state.visible changes the class changes and the transition takes place. The transition property in CSS is basically all the transitions separated by commas. Within the transition the first argument is the property to be modified (say height, width etc), second is transition-duration that is the time taken for the transition and third(optional) is transition-delay ie how much time after the transition has been initiated does the transition for the particular property take place. So when this.state.visible becomes true the .fadeIn class is attached to the object. The transition has height and width taking 0.5s each so that will take 0.5s to grow and after it is finished the opacity transition (which has a delay of 0.5s) will trigger and take a further 0.5s to get opacity 1. For the hiding it's the reverse.

Remember to have the OnClick event on the button handle the changing of this.state.visible.

like image 191
mrinalmech Avatar answered Nov 12 '22 02:11

mrinalmech


You could also achieve this with CSSTransitionGroup

const Example = ({items, removeItemHandler}) => {
  return (
    <div>
      <CSSTransitionGroup transitionName="fadeInput"
  transitionEnterTimeout={500}
  transitionLeaveTimeout={300}>
        {this.renderInputs().map(function(input) {
          return (
            <div key={input.id} className="my-item" onClick={removeItemHandler}>
              {item.name}
            </div>
          );
        })}
      </ReactCSSTransitionGroup>
    </div>
  );
};

When working with React, sometimes you want to animate a component directly after it has been mounted, or directly prior to it being unmounted. Like in your example, Let’s say you map over an array of objects and render a list in your application. Now let’s say you want to add animations to fade-in new items that have been added to the array or fade-out items as they are removed from the array. The CSSTransitionGroup component takes in transitionEnterTimeout and transitionLeaveTimeout as props. What these values represent are the duration in milliseconds of your enter and leave transitions.

like image 40
Tal Avissar Avatar answered Nov 12 '22 00:11

Tal Avissar


A simple way to achieve this with styled components...

const Popup = styled.div`
  width: 200px;
  height: 200px;
  transition: opacity 0.5s;
  opacity: ${({ showPopup }) => (showPopup ? '1' : '0')};
`;

<Popup showPopup={showPopup}>
  {...}
</Popup>
like image 4
Mathiasfc Avatar answered Nov 12 '22 02:11

Mathiasfc