0

I'm using React with Redux, and I have the following situation. In my component I have a div that holds and image, and the component is also receiving a property from my Redux state which is called showIcon. So, if showIcon is not null, I want the image to be displayed for 5 seconds, and once the 5 seconds passes, I want it to disappear and set the showIcon value to null by dispatching an action that I have like updateShowIcon(null);. How can I do this properly in React, and how can I use CSS to show and animate the icon as I want?

import React, { Component } from 'react';

class MyComp extends Component {
    render() {
        return (
            <div style={styles.mainDiv}>
                 <div style={styles.childDiv}>
                            {
                                this.props.showIcon &&
                                <div style={styles.iconStlyes}>
                                    <img src={process.env.PUBLIC_URL + '/icons/myicon.png'}/>
                                </div>
                            }
                            // partially removed for brevity, some other component
                </div>
            </div>
        );
    }
}

const styles = {
    iconStlyes: {
        position: 'absolute',
        zIndex: 10,
    },
    mainDiv: {
        overflow: 'auto',
        margin: 'auto',
        height: 'calc(100vh - 64px)',
        padding: 0,
    },
    childDiv: {
        height: 'calc(100vh - 64px)',
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
    },
};

export default MyComp;

2 Answers 2

1

Whenever I detect a change in componentWillReceiveProps I would create a timer and dispatch the action. Remember to clear the timeout on componentWillUnmount.
The idea is based on you showing and hiding the icon with css and not with react conditional rendering, so once you need to show the icon you add the class show or remove it once you don't need to show it.
It would probably look like this:

componentWillReceiveProps(nextProps){
  if (nextProps.showIcon && nextProps.showIcon !== this.props.showIcon){
    this.timer = setTimeout(() => {nextProps.updateShowIcon(null)}, 5000);
  }
}

componentWillUnmount(){
  clearTimeout(this.timer);
}

render() {
  const {showIcon} = this.props;
    return (
        <div style={styles.mainDiv}>
             <div style={styles.childDiv}>      
               <div style={styles.iconStlyes} className={`${showIcon ? 'show':''} icon-container`}>
                 <img src={process.env.PUBLIC_URL + '/icons/myicon.png'}/>
               </div>   
            </div>
        </div>
    );
}

and your css for a simple fade animation:

.icon-container{
  opacity: 0;
  transition: opacity: 500ms ease-in;
}

.icon-container.show{
  opacity: 1;
}
Sign up to request clarification or add additional context in comments.

Comments

0

If it is important for you to use the store state then you can manage the showIcon property via componentWillReceiveProps(nextProps) and do something like:

componentWillReceiveProps(nextProps){
  if(!this.props.showIcon && nextProps.showIcon){
      setTimeout(()=>dispatch(updateShowIcon(null)),5*1000);
  }
  //manage clear timeout if necessary 
}

But for the animation part its better to use the showIcon property as a class and not for adding/removing it from the DOM, like:

<div style={styles.iconStlyes} className={this.props.showIcon?'show':'hide'}>
    <img src={process.env.PUBLIC_URL + '/icons/myicon.png'}/>
</div>

and the styles should manage it:

iconStyles: {
    position: 'absolute',
    zIndex: 10;
    transition: //effects of specified or all attributes
    &.show{
       visibility: visible;//display:block
     }
    &.hide{
       visibility: hidden;//display:none
     }
}

2 Comments

You should save the timeout inside this.timer so you will be able to clear it in componentWillUnmount
I added it with comments. its just weird to me to hold a global state for the showing and hiding of an icon. I imagined it more like a 'current user state' rather then 'all users' ,but I guess anything possible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.