当前位置: 首页 > java >正文

React系列——HOC高阶组件的封装与使用

技巧一:复用组件逻辑

具体而言,高阶组件是参数为组件,返回值为新组件的函数

const EnhancedComponent = higherOrderComponent(WrappedComponent);

For example:
参数复用

const withSize = (Component) => {return class toSize extends Component {state = {xPos: document.documentElement.clientWidth,yPos: document.documentElement.clientHeight}getPos = () => {this.setState({xPox: document.documentElement.clientWidth,yPos: document.documentElement.clientHeight})}componentDidMount(){window.addEventListener('resize', this.getPos)}componentWillUnmount(){window.removeEventListener('resize', this.getPos)}render() {return <Component {...this.state}/>}}
}class Foo extends Component {render() {return (<div><p>x:{ this.props.xPos} -- y: {this.props.yPos} </p></div>)}
}class Sub extends Component {render() {return (<div><button>x:{ this.props.xPos} -- y: {this.props.yPos} </button></div>)}
}const SubWithSize = withSize(Sub)
const FooWithSize = withSize(Foo)class App extends Component {render() {return (<div><SubWithSize /><FooWithSize /></div>	)}
}

函数逻辑复用

// PhotoList.js
import React from 'react'
import withFetch from '../withFetch'const url = 'https://www.abc.com/photos?_limit=5const PhotoList = ({ list }) => {return (<ul> {list.map((photo) => {return <li key={photo.id}> 图片URL{photo.url}</li>})}</ul>)
}
export default withFetch(PhotoList, url)
// UserList.js
import React from 'react'
import withFetch from '../withFetch'const url = 'https://www.abc.com/users?_limit=5const UserList = ({ list }) => {return (<ul> {list.map((user) => {return <li key={user.id}> 用户名:{user.name}</li>})}</ul>)
}
export default withFetch(UserList, url)
import React from 'react'
import axios from 'axios'const withFetch = (Component, url) => {return class WithFetchComponent extends React.Component {state = {list: []}async componentDidMount() {const { data: list } = await axios.get(url)this.setState({list})}render() {return <Component {...this.props} list={this.state.list} /}}}
}

技巧二:组件的异步加载

利用lazy、suspense来实现组件的异步加载

  • 1、lazy引入异步组件
import ReactDOM from 'react-dom'
import React, { Component, lazy, Suspense } from 'react'
const sub = lazy(() => import('./Sub'))

2、suspense调用组件

class App extends Component {render() {return (<div>/*fallback的作用是在异步加载的空档中填充一些内容让页面可以正常渲染 */<Suspense fallback = { <div>loading</div> }><Sub /></Suspense></div>)}
}ReactDOM.render(<App />,document.getElementById('rroot')
)

技巧三:组件的生命周期

在这里插入图片描述

Mounting(挂载)

  • constructor(): 在 React 组件挂载之前,会调用它的构造函数。
  • getDerivedStateFromProps(): 在调用 render 方法之前调用,并且在初始挂载及后续更新时都会被调用。
  • render(): 唯一必须实现的纯函数;
  • componentDidMount(): 在组件挂载后(插入 DOM 树中)立即调用。

Updating(更新)

  • componentDidUpdate(): 在组件更新后立即调用

Unmounting(卸载)

  • componentWillUnmount(): 在组件卸载后理解调用

For example:

class App extends Component {constructor(props) {super(props)this.state = { count: 0 }console.log('cons');}onclick = () => {this.setState({count: this.state.count + 1})}componentDidMount(){console.log('did mount');}componentDidUpdate(){console.log('did update');}componentWillUnmount(){console.log('will unmount');}return() {console.log('render')return (<div><p> {this.state.count} </p><button onclick={this.onclick}>add</button></div>)}// 执行顺序:()
// cons -> render -> did mount (mounting阶段)
// -> render -> did update (updating阶段)
// -> will unmount (unmounting阶段)

技巧四:组件的优化

  • 避免无数据更新的自组件反复更新
    在这里插入图片描述
import ReactDOM from 'react-dom'
import React, { Component, PureComponent, memo } from 'react'//组件的优化一: 类组件
class Sub extends Component //方法二:替换成PureComponent {// 方法一shouldComponentUpdate(nextProps, nextState){if (nextProps.name === this.props.name) {return false;}return true;}render() {console.log('sub render');return (<div>sub</div>)}
}//组件的优化二: 函数组件
const Sub = memo((params) => {console.log('sub render');return (<div>sub</div>)
})class App extends Component {state = {count: 0}onclick = () => {this.setState({count: this.state.count + 1})}callback = () => {}render() {return (<div><Sub name="zhangsan" />// 函数同理<Sub func={this.callback} /><p> {this.state.count} </p><button onclick={this.onclick}>add</button></div>)}
}ReactDOM.render(<App />,document.getElementById('rroot')
)
http://www.xdnf.cn/news/5814.html

相关文章:

  • 使用ZYNQ芯片和LVGL框架实现用户高刷新UI设计系列教程(第十二讲)
  • (2)python开发经验
  • 下周,Coinbase将被纳入标普500指数
  • windows c++ (9) 程序内注册服务并修改登录账户
  • 使用 `aiohttp` 构建高效的异步网络爬虫系统
  • 一次讲清 FP32 / FP16 / BF16 / INT8 / INT4
  • VR和眼动控制集群机器人的方法
  • 青少年编程与数学 02-019 Rust 编程基础 10课题、函数、闭包和迭代器
  • 机器学习中分类模型的常用评价指标
  • 设计模式系列(03):设计原则(二):DIP、ISP、LoD
  • SpringBoot与Eventuate Tram整合 - 实现转账最终一致性系统
  • 解锁生命周期评价密码:OpenLCA、GREET 与 R 语言的融合应用
  • 基于 Amazon Bedrock 和 Amazon Connect 打造智能客服自助服务 – 设计篇
  • 【阿里云】阿里云 Ubuntu 服务器无法更新 systemd(Operation not permitted)的解决方法
  • Java Solon v3.3.0 发布(国产优秀应用开发基座)
  • Spring Boot Swagger 安全防护全解析:从旧版实践到官方规范
  • Spring Boot 跨域问题全解:原理、解决方案与最佳实践
  • Tomcat和Nginx的主要区别
  • 【MySQL】第三弹——表的CRUD进阶(一)数据库约束
  • 地址簿模块-01.需求分析
  • D-Pointer(Pimpl)设计模式(指向实现的指针)
  • 在VSCode中接入DeepSeek的指南
  • 【时时三省】(C语言基础)使用字符串处理函数
  • 基于Spring Boot+Layui构建企业级电子招投标系统实战指南
  • 人脸识别系统中的隐私与数据权利保障
  • ‌OPE.AI开放平台:一站式企业AI应用引擎
  • 前端学习(2)—— CSS详解与使用
  • centos7.x下,使用宝塔进行主从复制的原理和实践
  • 博客系统技术需求文档(基于 Flask)
  • R语言绘图 | 渐变火山图