React核心包如何降级
eg:代表代码对照
若文章有误,欢迎读者指出
安装17.0.2的React核心包
npm i -S react@17.0.2 react-dom@17.0.2 核心包降级
入口文件重新引入ReactDOM、配置
17.0.2入口文件
1 2 3 4 5 6 7 8 9
| import React from 'react' import ReactDOM from 'react' import App from './App'
ReactDOM.render( <App />, document.getElementById('root') )
|
18.2入口文件
1 2 3 4 5 6 7 8 9 10
| import React from 'react' import ReactDOM from 'react-dom/client' import App from './App'
const root = ReactDOM.createRoot(document.getElementById('root')) root.render( <App /> )
|
过渡动画组件
安装react-transition-group,它是react的第三方模块
npm i -S react-transition-group
自定义动画
- 安装完引入
CSSTransition标签,并对齐进行配置
import { CSSTransition } from 'react-transition-group'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| import { CSSTransition } from 'react-transition-group'
class Transition extends Component { state = { show: false } handleClick = () => { this.setState({ show: !this.state.show }) } render() { return ( <div> <h3>过渡动画</h3> {/* 2. 使用CSSTransition,并对其配置 */} <CSSTransition in={this.state.show} // 动画开关 timeout={2000} // 动画时长 classNames='donghua' // class组 unmountOnExit // 可选,加上代表离场动画执行完毕删除当前节点 > <div>动画元素</div> </CSSTransition> <button onClick={this.handleClick}>开关</button> </div> ) } }
|
- 书写样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| .donghua-enter { opacity: 0; } .donghua-enter-active { opacity: 1; transition: opacity 2000ms; } .donghua-exit { opacity: 1; } .donghua-exit-active { opacity: 0; transition: opacity 2000ms; }
|
- 引入动画样式到组件中
import './trans.css'
使用动画库
animate.css动画库集成到react-transition-group动画模块中
Animate.css官网
安装插件【已经安装的不需要重复安装】
npm i -S react-transition-group
npm i -S animate.css
入口文件引入动画库
// 使用动画库
import 'animate.css'
组件中使用
引入CSSTransition标签:import { CSSTransition } from 'react-transition-group'
1 2 3 4 5 6 7 8 9 10 11 12 13
| <CSSTransition in={this.state.show} timeout={2000} classNames={{ enter: 'animate__animated', enterActive: 'animate__fadeIn', exit: 'animate__animated', exitActive: 'animate__fadeOut' }} unmountOnExit > <div>这个是动画元素</div> </CSSTransition>
|
列表过渡动画
多个CSSTransition标签这时候需要TransitionGroup动画组包裹住
引入CSSTransition和TransitionGroup标签
import { CSSTransition, TransitionGroup } from 'react-transition-group'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| import React, { Component } from 'react' import { CSSTransition, TransitionGroup } from 'react-transition-group'
export default class Transition3 extends Component { state = { list: [1, 2, 3, 4], show: false } handleClick = () => { this.setState({ show: !this.state.show }, () => { console.log(this.state.show) }) } render() { return ( <div> <button onClick={this.handleClick}>动画</button> {/* 使用TransitionGroup标签 */} <TransitionGroup> { this.state.list.map((item, index) => { return ( <CSSTransition in={this.state.show} timeout={1000} // classNames="myfade" unmountOnExit onEntered={(el) => { el.style.color = 'blue' }} //钩子函数等价于enter appear={true} //启动首屏 首屏就执行动画 key={index} > <div> {item} </div> </CSSTransition> ) }) } </TransitionGroup> </div> ) } }
|
路由过渡动画【使用V5版本React-Router,,,5.3.0】
安装路由模块
路由模块不是react自带模块,需要安装第三方模块
npm i -S react-router-dom
入口文件引入hash路由模式,HashRouter标签
import { HashRouter } from 'react-router-dom'
使用HashRouter标签
1 2 3
| <HashRouter> <App /> </HashRouter>,
|
回到根组件配置二级路由,引入路由需要的标签和组件,由于使用17.0.2版本引入一下高阶组件withRouter,使用location
import { Switch,Route,Link,withRouter } from 'react-router-dom'
import Home from './pages/Home'
import User from './pages/user'
1 2 3 4 5 6 7 8 9 10 11
| return ( <> {/* react的空标签是<></> vue的空标签是template标签 */} <Link to="/home">home</Link> <Link to="/user">user</Link> <Switch> <Route path="/home" component={Home} /> <Route path="/user" component={User} /> </Switch> </> )
|
引入动画相关标签
import { CSSTransition, TransitionGroup } from 'react-transition-group'
完整代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| import React, { Component } from 'react' import { Switch, Route, Link, withRouter } from 'react-router-dom' import Home from './pages/Home' import User from './pages/User' import { CSSTransition, TransitionGroup } from 'react-transition-group'
class App extends Component { render() { console.log(this.props.location && this.props.location.pathname) return ( <> {/* react的空标签是<></> vue的空标签是template标签 */} <Link to="/home">home</Link> | <Link to="/user">user</Link> <TransitionGroup> <CSSTransition // in={true} //路由切换会自动触发组件的创建和销毁 timeout={2000} // classNames="myfade" classNames={{ enter: 'animate__animated', enterActive: 'animate__slideInLeft', exit: 'animate__animated', exitActive: 'animate__slideOutLeft' }} unmountOnExit //离场之后 页面组件销毁 key={this.props.location && this.props.location.pathname} > <Switch> <Route path="/home" component={Home} /> <Route path="/user" component={User} /> </Switch> </CSSTransition> </TransitionGroup> </> ) } }
export default withRouter(App)
|
利用高阶组件给组件添加动画
并不想让所有的路由都有动画效果,只是想对指定的页面有路由切换效果,可以利用高阶组件来完成。
定义高阶组件【函数组件】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| import React from 'react'
import { CSSTransition } from 'react-transition-group'
export default function TransHoc(Component) { return function newCom(props) { console.log('匹配:', props.match) return <CSSTransition in={props.match !== null} // 不为null代表匹配上了,开启动画 timeout={2000} classNames={{ enter: 'animate__animated', enterActive: 'animate__fadeIn', exit: 'animate__animated', exitActive: 'animate__fadeOut' }} unmountOnExit > <Component {...props} /> </CSSTransition> } }
|
使用高阶组件,如果有配置装饰器支持,可以使用高阶组件语法糖@高阶组件名称
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import React, { Component } from 'react'
import HOCTransition from '../HOC/HOCTransition'
class Home extends Component { render() { return ( <div style={{background: 'red'}}> Home </div> ) } }
export default HOCTransition(Home)
|
配置路由
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import React, { Component } from 'react' import { Route } from 'react-router-dom' import Home from './pages1/Home' import User from './pages1/User'
export default class App1 extends Component { render() { return ( <div> {/* <Route path="/home" component={ Home }></Route> <Route path="/User" component={ User }></Route> */} {/* component 注册的组件,会触发创建和销毁, children*/} {/* children初始化的时候,页面就会被创建,只有在匹配路由的时候才渲染 */} {/* children属性使用,17.0.2支持,18.2暂时没有替代方法 */} <Route path="/home" children={props => <Home {...props} />}></Route> <Route path="/User" children={props => <User {...props} />}></Route> </div> ) } }
|
注意:暂时没发现`children`如何使用`v6版本`替代,暂留、降级`v5版本`