高阶组件(简称:HOC):是react中用于重用组件逻辑的高级技术,它本身不是react中的组件,而是一个函数。这个函数接受一个react组件作为参数,并返回一个新组件,实现了对原有组件的增强和优化,可以对原有组件中的state,props和逻辑执行增删改操作,一般用于代码重用和组件增强优化
原始组件的路由信息会传入高阶组件的props中,可以对props进行增删改!!!
属性代理:通过创建新组件来包裹原始组件,把原始组件作为新组件的子组件渲染。
功能:可实现对原始组件的props数据更新 和组件模板更新优化
//一般来说,高阶组件中的父组件,会对原始组件模板做增强优化
return (
)
props由父组件传递给子组件,对子组件而言,props是只读的。由于props是只读的,不能改,所以在子组件中要对它进行深复制然后再修改
//高阶组件向原始组件添加路由信息
return (
)
对props数据进行增删改操作:
var {match,...tempObj}=this.tempProps
this.tempProps = tempObj
//把tempProps对象解析为match和tempObj并赋值,剩下的tempObj没有含有match字段所以直接取值即可得到没有含有match字段的props对象
属性代理只能操作props数据,不能操作state数据,无法调用原始组件的state,如果需要修改state数据请使用反向继承实现。
反向继承:通过创建新组建继承自原始组件,把原始组件作为父类
功能:可实现对原始组件的state状态数据更新 和 组件模板更新。注意:反向继承结构中新组件和原始组件必须都是类组件。
反向继承指的是让新组件类继承原始组件类,新组件为子类,原始组件为父类,因为当前组件类继承与原始组件类,子类可以直接调用父类的数据。
需要使用super调用父类的render渲染函数,渲染父类模板
return
{super.render()}
function MyHoc(OldCom){
return class NewCom extends React.Component{
render(){
let newProps = { age: 10, sex: '男' }
return (
)
}
}
}
属性代理(上)或者(反向继承)
function MyHOC (OldCom){
return class NewCom extends OldCom{
componentDidMount() {
this.setState({ name: '李四' })
}
render() {
return super.render()
}
}
}
export default MyHOC
import MyHoc1 from “./MyHOC1”
export default MyHoc2(MyCom)
高阶组件的渲染劫持:通过高阶组件把原始组件的模板进行修改和替换,如果要返回原始组件模板,把原始组件作为子组件返回即可。
return
渲染劫持指对一个组件渲染内容的装饰或修改,一般通过高阶组件来实现,把一个组件传入高阶组件,可以对这个组件的模板进行修改后执行渲染,也可以阻止组件渲染,并修改组件中的数据和逻辑
渲染劫持的应用:一般用于一些需要登录状态的页面,在路由请求渲染页面(订单页)之前,使用告诫组件判断是否已登录,如果已登录,返回订单页模板,如果没有登录,返回空,并跳转到登录页
hooks是react新版本提供的组合式API语法,类似于vue3组合式API,也叫hooks
hooks有什么用:使函数式组件拥有组件状态和生命周期功能,提高运行效率,避免this指向问题。
useState定义的引用类型数据,更新时,需要修改数据的内存地址,也就是深拷贝,才会更新视图。
import React, { useState } from “react”
使用useState创建状态数据,参数是默认值,返回值是数组,数组中第一个值是状态数据的变量名,第二个值是更新函数,调用会刷新视图。使用useState创建状态数据需要引入useState函数。
import { useState ,useEffect} from ‘react’;
const [name, setName] = useState(“名字”)
自定义状态name: {name}-{age}
setName(“李四”)
import { useEffect} from ‘react’;
使用useEffect函数实现函数式组件的生命周期,默认参数是回调。当组件初始化和状态数据更新时,执行回调函数,相当于render
useEffect(()=>{
// 如果不加第二个参数, 初始化时调用, 任何状态更新都会调用
console.log("effect");
})
第二个参数可控制回调的调用时机,[]表示只在初始化时调用,相当于生命周期componentDidMount,在这里请求数据
useEffect(()=>{
// 如果第二个参数是空数组, 则只在初始化时调用,状态更新时不会调用
console.log("组件初始化");
},[])
useEffect(()=>{
// 如果第二个参数数组中有状态名, 则只会在数组中的状态更新时调用
console.log("组件初始化或count或arr更新");
},[count,arr])
等count,arr更新时才会执行第一个回调函数
在react-router6.0中所有的组件都没有路由信息,也没有withRouter, 需要使用hooks语法引入路由信息, 所以,我们可以自己封装withRouter高阶组件。由于路由数据是在props中,所以使用属性代理方式。
import { useHistory, useLocation, useRouteMatch } from "react-router-dom"
function myHoc(OldCom){
// 必须返回函数式组件, 因为hooks语法不能用于类组件
return ()=>{
// 从hooks中获取路由信息
const history = useHistory()
const location = useLocation()
const match = useRouteMatch()
const tempProps = {history, location, match}
// 返回组件模板
return
}
}
export default myHoc