This article shares the development process of a react animation component. Take a pop-up from the bottom as an example:
A pop-up from the bottom similar to the action sheet.
thinking
1. Click the bottom of the button to pop up the pop-up box
2. Mask background display at the same time
3. When you click to mask the background, the pop-up box pops down and the background disappears.
1, Background mask implementation
Considering that the mask is used in many places, it is encapsulated as a component. Combined with redux development, the code is as follows:
//app.js introduces the mask component into the global app, which is available globally
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Header from './components/Header'
import Footer from './containers/Footer'
import Find from './components/Find'
import Slidebar from './components/Slidebar'
import PlayList from './containers/PlayList'
import Mask from './containers/Mask'
class App extends Component {
render() {
return (
<div>
<div className='header-div'>
<Header pathName={this.props.location.pathname} />
</div>
<Footer />
<Slidebar />
<PlayList />
<Mask/>
</div>
);
}
}
export default App;
//containers Under directory mask Component container. Responsible for redux Establish a connection
import { connect } from 'react-redux'
import Mask from '../components/Mask'
//take state Mapped to component props
const mapStateToProps = (state, ownProps) => ({
isShowPop:state.showPopReducer.isShowPop
})
export default connect(mapStateToProps)(Mask)
components Lower mask Be responsible for ui display
import React, {Component} from 'react'
import {showPop} from '../actions/popAction'
export default class Mask extends Component {
statusName = 'fade-enter'
render() {
return (
<div
ref='maskDiv'
className = {this.props.isShowPop?'':''}
onClick={e=> this.clickHandle(e)}></div>
)
}
componentDidMount() {
this.refs.maskDiv.className = 'mask fade-enter';
}
componentWillUpdate(nextProps, nextState) {
if(nextProps.isShowPop){
this.refs.maskDiv.className = 'mask fade-enter-active'
}else{
this.refs.maskDiv.className = 'mask fade-leave-active'
}
setTimeout(()=>{
if(nextProps.isShowPop){
//this.refs.maskDiv.className = 'mask fade-enter';
}else{
this.refs.maskDiv.className = 'mask fade-leave';
}
},600)
}
clickHandle(e) {
const {dispatch} = this.props;
//Distribute action to indicate departure
dispatch(showPop(false))
}
}
//Mask style
.mask{
position: fixed;
left: 0;
top: 0;
bottom: 0;
right: 0;
content: '';
background: rgba(0,0,0,.5);
z-index:10001;
}
//Mask in and out over animation
.fade-enter-active {
z-index: 10001!important;
opacity: 1;
transition: opacity 600ms ease-in;
}
.fade-enter ,.fade-leave {
z-index: -1!important;
opacity: 0;
}
.fade-leave-active {
z-index: 10001!important;
opacity: 0;
transition: opacity 600ms ease-in;
}
//popAction.js
import * as actionTypes from '../constants/constant'
export function showPlayListAction(isShow){
return{
type:actionTypes.SHOW_PLAYLIST_POP,
isShow
}
}
function startAnimate(startAnimate){
return{
type:actionTypes.SHOW_POP,
startAnimate
}
}
export function showPop(showPop){
//Using this distribution method to refer to the asynchronous data flow action distribution, you need to refer to the middleware Redux thunk. Please refer to the official website example
return (dispatch,getState) =>{
if(showPop){
dispatch(showPlayListAction(showPop))
dispatch(startAnimate(showPop));
}else{
dispatch(startAnimate(showPop));
dispatch(showPlayListAction(showPop));
// setTimeout(() => {
// dispatch(showPlayListAction(showPop))
// }, 600);
}
}
}
Development of spring frame components
//animation.js animation package component
import React, { Component } from 'react'
export default class Animation extends Component {
render(slot,isShow,name) {
return (
<div className={isShow?'animation '+name+'-enter-active':'animation '+name+'-leave-active'}>
{slot}
</div>
)
}
componentWillUpdate(nextProps, nextState) {
console.log(nextProps, nextState)
}
}
//The subcomponent to execute the animation.
import React, {Component} from 'react'
import {fetchMusicData} from '../actions/musicDataAction'
import {showPop} from '../actions/popAction'
import Animation from './Animation'
import {selectSong} from '../actions/playMusicAction'
export default class PlayList extends Animation {
constructor(props) {
super(props)
this.state = {
isShow: false
}
}
render() {
//return (
return super.render(
<div className='play-list-wraper' onClick={e => this.clickHandle(e)}>
<div
className={this.props.isShowPop
? 'play-list '
: 'play-list '}>
<div className='header-bar'>
<div className='play-type'>
<i className='icon icon-music-random'/>
<span>{'List loop'}({33})</span>
</div>
<div className='op-div'>
<label>
<i className='icon-add-project'/>
<span>Collection</span>
</label>
<label>
<i className='icon-delete'/>
<span>empty</span>
</label>
</div>
</div>
<div className='play-content'>
{this
.props
.tracks
.map((item, index) => <div key={index} onClick={e=> this.playSong(e,item.hash)} className='music-item'>
<div className='music-name'>
<label>{item.filename}</label>
<span></span>
</div>
<div className='music-name'></div>
</div>)}
</div>
</div>
</div>, this.props.isShowPop, 'slide')
}
clickHandle(e) {
if (e.target.className.indexOf('play-list-wraper') !== -1) {
const {dispatch} = this.props;
dispatch(showPop(false))
}
}
playSong(e,index){
const {dispatch} = this.props;
dispatch(selectSong(index));
}
componentWillMount() {
const {dispatch} = this.props;
dispatch(fetchMusicData());
}
}
//Animation css
.animation{
position: fixed;
z-index: 10002;
width: 100%;
bottom: 0;
transform: translate3d(0,100%,0)
}
.slide-enter-active{
transition: transform 0.6s;
transform:translate3d(0,0,0)!important;
}
.slide-leave-active{
transition: transform 0.6s;
transform:translate3d(0,100%,0)!important;
}
The above is only part of the code, and the code used in combination with redux is not posted. Please check the complete code react imitates Netease cloud music