React 基础巩固(二十五)——高阶组件
高阶函数
定义:接收一个或多个函数作为输入
或 输出一个函数
的函数 JS 中常用的map
、filter
、reduce
都是高阶函数
高阶组件(Higher-Order Components, HOC)
定义:高阶组件是参数为函数,返回值为新组件的函数 高阶组件本质是函数 高阶组件并不是 React API 的一部分,它是基于 React 的组合特性而形成的设计模式
import React, { PureComponent } from "react" ;
function hoc ( Cpn ) { class NewCpn1 extends PureComponent { render ( ) { return < Cpn / > ; } } return NewCpn1; function NewCpn2 ( props ) { } return NewCpn2;
} class HelloWorld extends PureComponent { render ( ) { return ( < div> < h1> hello world< / h1> < / div> ) ; }
} const HelloWorldHOC = hoc ( HelloWorld) ; export class App extends PureComponent { render ( ) { return ( < div> < HelloWorld / > < HelloWorldHOC / > < / div> ) ; }
} export default App;
高阶组件的应用场景(一)—— 用户信息增强
import React, { PureComponent } from "react" ;
function enhanceUserInfo ( OriginCmp ) { class NewComponent extends PureComponent { constructor ( ) { super ( ) ; this . state = { userInfo : { name : "outman" , level : 123 , } , } ; } render ( ) { return < OriginCmp { ... this . props} { ... this . state. userInfo} / > ; } } return NewComponent;
} export default enhanceUserInfo;
import React, { PureComponent } from "react" ;
import enhanceUserInfo from "./enhance_props" ; const Home = enhanceUserInfo ( function Home ( props ) { return ( < h1> Home : { props. name} - { props. level} - { props. age} < / h1> ) ;
} ) ; const Profile = enhanceUserInfo ( function Profile ( props ) { return ( < h1> Profile : { props. name} - { props. level} < / h1> ) ;
} ) ; const Hello = enhanceUserInfo ( function Hello ( props ) { return ( < h1> Hello : { props. name} - { props. level} < / h1> ) ;
} ) ; export class App extends PureComponent { render ( ) { return ( < div> < Home age= { "888" } / > < Profile / > < Hello / > < / div> ) ; }
} export default App;
高阶组件的应用场景(二)—— 拦截并处理Context传参
import { createContext } from "react" ; const ThemeContext = createContext ( ) ; export default ThemeContext;
构建 App.jsx,通过 ThemeContext.Provider
传递参数给<Product/>
import React, { PureComponent } from "react" ;
import ThemeContext from "./context/theme_context" ;
import Product from "./Product" ; export class App extends PureComponent { render ( ) { return ( < div> < ThemeContext. Provider value= { { color : "red" , size : 18 } } > < Product / > < / ThemeContext. Provider> < / div> ) ; }
} export default App;
构建 Product.jsx, 在 Product 中,通过 ThemeContext.Consumer
消费参数
import React, { PureComponent } from "react" ;
import ThemeContext from "./context/theme_context" ;
export class Product extends PureComponent { render ( ) { return ( < div> Product : < ThemeContext. Consumer> { ( value ) => { return ( < h2> theme : { value. color} - { value. size} < / h2> ) ; } } < / ThemeContext. Consumer> < / div> ) ; }
} export default Product;
若每次都要采用上述方式,通过ThemeContext.Consumer
消费参数,太过繁琐。故,可以利用高阶组件进行处理。 构建高阶组件 with_theme
import ThemeContext from "./theme_context" ; function withTheme ( OriginComponent ) { return ( props ) => { return ( < ThemeContext. Consumer> { ( value ) => { return < OriginComponent { ... value} { ... props} / > ; } } < / ThemeContext. Consumer> ) ; } ;
} export default withTheme;
import React, { PureComponent } from "react" ;
import withTheme from "./context/with_theme" ;
export class Product extends PureComponent { render ( ) { const { color, size } = this . props; return ( < div> Product : { color} - { size} < / div> ) ; }
} export default withTheme ( Product) ;
高阶组件的应用场景(三)—— 登陆鉴权
function loginAuth ( OriginComponent ) { return ( props ) => { const token = localStorage. getItem ( "token" ) ; if ( token) { return < OriginComponent { ... props} / > ; } else { return < h2> 请先登陆< / h2> ; } } ;
} export default loginAuth;
import React, { PureComponent } from "react" ;
import Cart from "./Cart" ; export class App extends PureComponent { constructor ( ) { super ( ) ; this . state = { isLogin : false , } ; } loginClick ( ) { localStorage. setItem ( "token" , "test token value" ) ; this . setState ( { isLogin : true , } ) ; } render ( ) { const { isLogin } = this . state; return ( < div> < button onClick= { ( e ) => this . loginClick ( ) } > 登录< / button> < Cart / > < / div> ) ; }
} export default App;
构建Cart.jsx,并用loginAuth包裹Cart进行鉴权处理
import React, { PureComponent } from "react" ;
import loginAuth from "./login_auth" ; export class Cart extends PureComponent { render ( ) { return ( < div> < h2> Cart< / h2> < / div> ) ; }
} export default loginAuth ( Cart) ;
高阶组件的应用场景(四)—— 打印界面渲染时间
import { PureComponent } from "react" ; function logRenderTime ( OriginComponent ) { return class extends PureComponent { UNSAFE_componentWillMount ( ) { this . beginTime = new Date ( ) . getTime ( ) ; } componentDidMount ( ) { this . endTime = new Date ( ) . getTime ( ) ; const interval = this . endTime - this . beginTime; console. log ( ` 当前页面: ${ OriginComponent. name} 的渲染花费: ${ interval} ms ` ) ; } render ( ) { return < OriginComponent / > ; } } ;
} export default logRenderTime
import React, { PureComponent } from 'react'
import Detail from './Detail' export class App extends PureComponent { render ( ) { return ( < div> < Detail> < / Detail> < / div> ) }
} export default App
构建Detail.jsx,并通过logRenderTime拦截Detail组件,打印其界面渲染时间
import React, { PureComponent } from "react" ;
import logRenderTime from "./log_render_time" ; export class Detail extends PureComponent { render ( ) { return ( < div> < h2> Detail Page< / h2> < ul> < li> 数据列表1 < / li> < li> 数据列表2 < / li> < li> 数据列表3 < / li> < li> 数据列表4 < / li> < li> 数据列表5 < / li> < li> 数据列表6 < / li> < li> 数据列表7 < / li> < li> 数据列表8 < / li> < li> 数据列表9 < / li> < li> 数据列表10 < / li> < / ul> < / div> ) ; }
} export default logRenderTime ( Detail) ;