React implements dynamic pop-up window component

React implements dynamic pop-up window component

When we write some UI components, if we don't consider the animation, it is very easy to achieve. The main thing is to switch the presence or absence (similar to the v-if attribute in Vue) or the visibility (similar to the v-show attribute in Vue).

1. Pop-ups without animation

In React, this can be achieved like this:

interface ModalProps {
  open: boolean;
  onClose?: () => void;
  children?: any;
}
const Modal = ({open.onClose, children}: ModalProps) => {
  if (!open) {
    return null;
  }
  return createPortal(<div>
    <div classname="modal-content">{children}</div>
    <div classname="modal-close-btn" onclick="{onClose}">x</div>
  </div>, document.body);
};

Directions:

const App = () => {
  const [open, setOpen] = useState(false);

  return (
    <div classname="app">
      <button onclick="{()" ==""> setOpen(true)}>show modal</button>
      <modal open="{open}" onclose="{()" ==""> setOpen(false)}>
        Modal content
      </modal>
    </div>
  );
};

Here we use the open attribute to control whether to display or not, but there is no gradient effect at all.

If we want to achieve animation effects such as fade and zoom, we need to modify this.

2. Create animated pop-ups yourself

When many students implement animation effects themselves, they often find that the animation works when it is displayed, but not when it is closed. It’s all because the timing of the animation was not controlled well. Here we first implement the flow of dynamic effects ourselves.

When I first started implementing it, the animation only had a start state and an end state, and it required a lot of variables and logic to control the animation.

Later, I referred to the implementation of react-transition-group component, which split the animation into several parts and controlled each part separately.

  1. The order of expansion animation: enter -> enter-active -> enter-done;
  2. The order of closing animation effects: exit -> exit-active -> exit-done;

The animation process is in the process of enter-active and exit-active .

We use a variable active to control whether the closing animation has been executed, and the parameter open only controls whether the expansion animation or the closing animation is executed.

The popup window is destroyed only when both open and active are false.

const Modal = ({ open, children, onClose }) => {
  const [active, setActive] = useState(false); // Pop-up window existence cycle if (!open && !active) {
    return null;
  }

  return ReactDOM.createPortal(
    <div classname="modal">
      <div classname="modal-content">{children}</div>
      <div classname="modal-close-btn" onclick="{onClose}">
        x
      </div>
    </div>,
    document.body,
  );
};

Here we continue to add changes in the animation process:

const [aniClassName, setAniClassName] = useState(''); // Animation class

// Transition execution completed listening function const onTransitionEnd = () => {
  // When open is rue, the end state is 'enter-done'
  // When open is not false, the end status is 'exit-done'
  setAniClassName(open ? 'enter-done' : 'exit-done');

  // If open is false, the pop-up window's life cycle ends when the animation ends if (!open) {
    setActive(false);
  }
};

useEffect(() => {
  if (open) {
    setActive(true);
    setAniClassName('enter');
    // setTimeout is used to switch classes and make transition happen setTimeout(() => {
      setAniClassName('enter-active');
    });
  } else {
    setAniClassName('exit');
    setTimeout(() => {
      setAniClassName('exit-active');
    });
  }
}, [open]);

The complete code of the Modal component is as follows:

const Modal = ({ open, children, onClose }) => {
  const [active, setActive] = useState(false); // Pop-up window existence cycle const [aniClassName, setAniClassName] = useState(''); // Animation class
  const onTransitionEnd = () => {
    setAniClassName(open ? 'enter-done' : 'exit-done');
    if (!open) {
      setActive(false);
    }
  };

  useEffect(() => {
    if (open) {
      setActive(true);
      setAniClassName('enter');
      setTimeout(() => {
        setAniClassName('enter-active');
      });
    } else {
      setAniClassName('exit');
      setTimeout(() => {
        setAniClassName('exit-active');
      });
    }
  }, [open]);

  if (!open && !active) {
    return null;
  }

  return ReactDOM.createPortal(
    <div classname="{'modal" '="" +="" aniclassname}="" ontransitionend="{onTransitionEnd}">
      <div classname="modal-content">{children}</div>
      <div classname="modal-close-btn" onclick="{onClose}">
        x
      </div>
    </div>,
    document.body,
  );
};

The flow process of the animation has been realized, and the style should also be written together. For example, we want to achieve a fade effect:

.enter {
  opacity: 0;
}
.enter-active {
  transition: opacity 200ms ease-in-out;
  opacity: 1;
}
.enter-done {
  opacity: 1;
}
.exit {
  opacity: 1;
}
.exit-active {
  opacity: 0;
  transition: opacity 200ms ease-in-out;
}
.exit-done {
  opacity: 0;
}

If you want to achieve the zoom effect, just modify these classes.

A pop-up window with animation has been implemented.

Directions:

const App = () => {
  const [open, setOpen] = useState(false);

  return (
    <div classname="app">
      <button onclick="{()" ==""> setOpen(true)}>show modal</button>
      <modal open="{open}" onclose="{()" ==""> setOpen(false)}>
        Modal content
      </modal>
    </div>
  );
};

Click the link to implement your own React pop-up window demo to see the effect.

Similarly, there are Toast and the like, which can also be implemented in this way.

3. react-transition-group

We borrowed the CSSTransition component in react-transition-group to achieve the dynamic effect. CSSTransition has encapsulated the process of dynamic expansion and closing for me. We can directly use this component when implementing pop-up windows.

There is an important property here: unmountOnExit , which means that the component will be uninstalled after the animation ends.

const Modal = ({ open, onClose }) => {
  // http://reactcommunity.org/react-transition-group/css-transition/
  // in property is true/false, true is to expand the animation, false is to close the animation return createPortal(
    <csstransition in="{open}" timeout="{200}" unmountonexit="">
      <div classname="modal">
        <div classname="modal-content">{children}</div>
        <div classname="modal-close-btn" onclick="{onClose}">
          x
        </div>
      </div>
    </csstransition>,
    document.body,
  );
};

After using the CSSTransition component, Modal's animation becomes much more convenient.

4. Conclusion

So far, the React Modal component to be animated has been implemented. Although there is no <transition> tag in React similar to the official definition of Vue, we can implement it ourselves or with the help of third-party components.

The above is the details of how to implement dynamic pop-up window components in React. For more information about React pop-up window components, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • React uses antd's upload component to implement the file form submission function (complete code)
  • Solution to React pure function component setState not refreshing the page update
  • Implementation of React star rating component
  • How to make React components full screen

<<:  Detailed explanation of Dockerfile to create a custom Docker image and comparison of CMD and ENTRYPOINT instructions

>>:  Explanation of the configuration and use of MySQL storage engine InnoDB

Recommend

Introduction to keyword design methods in web design

Many times, we ignore the setting of the web page ...

Some methods to optimize query speed when MySQL processes massive data

In the actual projects I participated in, I found...

Mac+IDEA+Tomcat configuration steps

Table of contents 1. Download 2. Installation and...

Website Building Tutorial for Beginners: Learn to Build a Website in Ten Days

The 10-day tutorial uses the most understandable ...

JavaScript Basics: Immediate Execution Function

Table of contents Immediately execute function fo...

Some slightly more complex usage example codes in mysql

Preface I believe that the syntax of MySQL is not...

Detailed explanation of using Docker to build externally accessible MySQL

Install MySQL 8.0 docker run -p 63306:3306 -e MYS...

JavaScript Regular Expressions Explained

Table of contents 1. Regular expression creation ...

Steps to export the fields and related attributes of MySQL tables

Need to export the fields and properties of the t...

CSS to achieve horizontal lines on both sides of the middle text

1. The vertical-align property achieves the follo...

How to clear default styles and set common styles in CSS

CSS Clear Default Styles The usual clear default ...

A solution to the abnormal exit of Tomcat caused by semaphore

I'm playing with big data recently. A friend ...

Detailed explanation of MySQL transaction processing usage and example code

MySQL transaction support is not bound to the MyS...

Analysis of MySQL latency issues and data flushing strategy process

Table of contents 1. MySQL replication process 2....