now, the user's request to the front-end page has not been satisfied with the realization of the function. It is more beautiful and interesting. In addition to the beauty of the overall UI, adding appropriate animation in the right place is often more expressive than static pages to achieve a more natural effect. For example, a simple loading animation or page switching effect can not only alleviate users' waiting mood, but also achieve the effect of brand publicity quietly through the use of brand logo.

React as the front-end development framework is more popular in recent years, put forward the concept of virtual DOM, change all DOM first occurs in the virtual DOM, to analyze the actual change "by DOM diff, and then reflected in the real DOM, thus greatly enhance the performance of web pages. However, in terms of animation implementation, React as a framework does not directly provide animation effects to components, it needs developers to achieve them, but most of the traditional web animation is realized by directly manipulating the actual DOM elements, which is obviously not recommended in React. So how do all the animations come true in React? The essence of all

animation is to continuously modify one or more attributes of the DOM element to produce a coherent change effect, thus forming animation. The implementation of animation in React is essentially the same as the traditional web animation, which is still the two way: the implementation of CSS3 animation and the modification of the element properties through JS. But in the actual implementation, to be more in line with the characteristics of React framework, can be divided into several categories:

  1. requestAnimationFrame (RAF) based on a timer or the interval
  2. based on a simple animation animation;

  3. CSS3;
  4. React CssTransitionGroup
  5. animation plug-in; combined with hook to achieve complex animation;
  6. other third party animation library.

, based on a timer or the interval of RAF animation

first, the realization of animation is to rely on the timer setInterval, setTimeout or requestAnimationFrame (RAF) directly modify the attributes of the DOM elements. Developers who are not familiar with React characteristics may habitually acquire real DOM nodes through ref or findDOMNode () , and directly modify their styles. However, the direct acquisition of real DOM through ref and its operation are not advocated and should be avoided as far as possible.

therefore, we need to link the methods of the timer or RAF to the DOM node properties through the state. First of all, we need to extract and change style related properties, to replace the state, and then add or modify state requestAnimationFrame timer continuously in the life cycle of an appropriate function, trigger assembly updates, in order to achieve animation effects.

to sample a progress bar, for example, is shown in the following code:

 / / state import use requestAnimationFrame to change React, {Component} from'react'export default class Progress extends; Component constructor (props) {{super (props; this.state) {percent:}} = 10; increase = (=>) {const; percent = this.state.percent; const = targetPercent percent > = 90; 100 + 10?: percent; const speed = (targetPercent - percent) / 400 let; start = null; const = animate timestamp => {if (start!) start = timestamp; const = progress timestamp currentProgress = const - start; Math.min (parseInt (speed * progress + percent, 10), targetPercent (this.setState) {; Percent: currentProgress if (currentProgress)}; < targetPercent) {window.requestAnimationFrame (animate);}}}; window.requestAnimationFrame (animate); decrease = (=> const) {percent = this.state.percent; const = targetPercent percent < 10? 0: percent - 10; const = speed (percent - targetPercent) / 400; let start = null; const = animate timestamp => {if (start!) start = timestamp; const = progress timestamp - start const Math.max (parseInt; currentProgress = (percent * - speed progress, 10), targetPercent (currentProgress); this.setState {percent:}); if (currentProgress > targetPercent) {window.reque StAnimationFrame (animate);}}; window.requestAnimationFrame (animate) render (const);} {{percent} = this.state; return (< div> < div className= "progress" > < div; className= > progress-wrapper & lt; div className= "progress-inner" style = {{width: `${percent}%`}} > < /div> < /div> < div className= "progress-info" > {percent}%< /div> < /div> < div className= "BTNs" > < button; onClick={this.decrease}> -< /button> < button onClick={this.increase}> +< /button> < /div> < /div>}

;}) in the example, we in increasedecrease function in animation ode>, requestAnimationFrame executive will perform the transition function in the browser to redraw each time before the calculation of the current progress of the width property and update the state, making the progress of re rendering. The example results are shown as follows:

the way to achieve good performance in the use of requestAnimationFrame, using pure JS implementation, not dependent on CSS, may appear off frames Caton phenomenon using the timer when. In addition, it is also necessary for the developer to calculate the state of its own according to the speed function, which is more complex.

two, CSS3 based simple animation

. When animation and transition appear and popularize in CSS3, we can easily use CSS to achieve changes in element styles instead of artificially computing real-time styles.


we still take the above progress as an example, the use of CSS3 to achieve the progress of dynamic effect, shown in the following code:

 import React {Component} from'react'export default class Progress extends; Component constructor (props) {{super (props; this.state) {percent:}} = 10; increase = (=> const) {percent = this.state.percent + 10; this.setState (percent {percent: > 100? 100: percent, decrease})} = (=> const) {percent = this.state.percent - 10; this.setState (percent {percent: < 0? 0: percent (render) {}}) with / above example, omitted.}
...}.Progress-inner {transition: width 400ms C Ubic-bezier (0.08, 0.82, 0.17, 1); / / other style as above, omitting}

... In the example, width is no longer the calculation of increase and decrease function, but directly or after setting the width. Note that the transition attribute in the CSS style, dynamic effect of the auto implemented properties style in the specified transition-property changes the speed curve and can set different speed effect. The effect of this example is shown below. We can see that unlike the last example, the progress data on the right side is directly changed to the target number, there is no specific change process, and the dynamic effect of the progress bar is no longer linear, and the effect is more vivid.

based on CSS3 method has higher performance, less code, but can only rely on the CSS effect for complex animation is also difficult to achieve. In addition, by modifying the state to achieve the animation effect, it can only be used in the nodes that already exist in the DOM tree. If you want to use this way to add components admission and departure animation, the need to maintain at least two state to achieve the entry and departure of animation, one of the state element is used to control the display, another state is used to change attribute control elements in the animation of. In this case, developers need to spend a lot of effort to maintain the animation logic of components, very complicated and complicated.

three, React CssTransitionGroup

React has animation plug-in provides developers with animation plug-in react-addons-css-transition-group, delivered by community maintenance, formed the react-transition-group now, the plug-in can easily realize the components of the entrances and exits when using animation, developers need to install additional. react-transition-group includes CSSTransitionGroup and TransitionGroup two animation plug-ins, the latter is the underlying API, the former is the further encapsulation of the latter, and it can be more convenient to achieve CSS animation. The following code example

with a dynamic increase of tab as an example,


 import React {Component} from {CSSTransitionGroup}'react'; import from'react-transition-group'; let uid = 2; export default class Tabs extends Component constructor (props) {{super (props; this.state) {activeId: = 1. TabData: [{id: 1, panel: 1'' option}, {id: 2, panel: 2'' option}]}}; addTab = (=> tab) {} / / add code... DeleteTab = (ID) => {/ / delete tab code render (const) {...} {tabData}, activeId = this.state; const renderTabs = (=> return) { ((item, index) {return (=> < div className={`tab-item${ = activeId tab-item-active'key={`tab${}`} >?':''}`}; {item.panel} < span className= "BTNs btn-delete onClick={" (=>); this.deleteTab (}> < /span> < /div>})} (return); < div> < div className= > < "tabs" CSSTransitionGroup; transitionName= "tabs-wrap" transitionEnterTimeout={500} transitionLeaveTimeout={500} > {renderTabs (<);}; / CSSTransitionGroup> < span className= "BTNs btn-add onClick={this.addTab}>"; +< /span> < /div> < div ClassName= "tab-cont" > cont < /div> < /div>}
);} / * tab * /.Tabs-wrap-ent increased dynamic animation

This concludes the body part