目录
一 使用步骤
二 显示鼠标坐标
三 鼠标随图片移动
四 设置displayName
五 传递props
高阶组件HOC: Higher-Order Component,是一个函数,接收要包装的组件,返回增强后的组件
目的:实现状态逻辑复用
高阶组件就相当于手机壳, 采用包装(装饰)模式
1 创建一个函数,名称约定以with开头
2 指定函数的参数,参数以大写字母开头(作为要渲染的组件)
3 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
4 渲染参数组件,同时将状态通过props传递给参数组件
5 调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
import React from "react";
import ReactDOM from "react-dom";
// 1 创建一个函数,名称约定以with开头
// 2 指定函数的参数,参数以大写字母开头(作为要渲染的组件)
function withMouse(WrappedComponent) {
// 3 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
class Mouse extends React.Component {
//鼠标状态
state = {
x: 0,
y: 0
}
//处理状态的逻辑代码
handleMouseMove = e => {
this.setState({
x: e.clientX,
y: e.clientY
})
}
//监听鼠标移动事件
componentDidMount() {
window.addEventListener("mousemove", this.handleMouseMove)
}
//解绑事件
componentWillUnmount() {
window.removeEventListener('mousemove', this.handleMouseMove)
}
render() {
//4 渲染参数组件,同时将状态通过props传递给参数组件
return
}
}
return Mouse;
}
const Position = props => (
鼠标当前位置:(x:{props.x},y:{props.y})
)
//调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
const MousePosition = withMouse(Position)
class App extends React.Component {
render() {
return (
{/*渲染增强后的组件*/}
)
}
}
ReactDOM.render( , document.getElementById("root"));
效果
加入鼠标随图片移动的功能
import imgage from "./images/cat.jpg"
const Cat = props => (
)
//调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
const MousePosition1 = withMouse(Cat)
效果
完整代码
import React from "react";
import ReactDOM from "react-dom";
import imgage from "./images/cat.jpg"
// 1 创建一个函数,名称约定以with开头
// 2 指定函数的参数,参数以大写字母开头(作为要渲染的组件)
function withMouse(WrappedComponent) {
// 3 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
class Mouse extends React.Component {
//鼠标状态
state = {
x: 0,
y: 0
}
//处理状态的逻辑代码
handleMouseMove = e => {
this.setState({
x: e.clientX,
y: e.clientY
})
}
//监听鼠标移动事件
componentDidMount() {
window.addEventListener("mousemove", this.handleMouseMove)
}
//解绑事件
componentWillUnmount() {
window.removeEventListener('mousemove', this.handleMouseMove)
}
render() {
//4 渲染参数组件,同时将状态通过props传递给参数组件
return
}
}
return Mouse;
}
const Cat = props => (
)
//调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
const MousePosition1 = withMouse(Cat)
const Position = props => (
鼠标当前位置:(x:{props.x},y:{props.y})
)
//调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
const MousePosition2 = withMouse(Position)
class App extends React.Component {
render() {
return (
{/*渲染增强后的组件*/}
)
}
}
ReactDOM.render( , document.getElementById("root"));
默认情况下,react使用组件名称作为displayName
使用高阶组件存在的问题: 得到的两个组件名称相同
解决办法: 设置displayName → 用于调试时区分不同的组件
效果
import React from "react";
import ReactDOM from "react-dom";
import imgage from "./images/cat.jpg"
// 1 创建一个函数,名称约定以with开头
// 2 指定函数的参数,参数以大写字母开头(作为要渲染的组件)
function withMouse(WrappedComponent) {
// 3 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
class Mouse extends React.Component {
//鼠标状态
state = {
x: 0,
y: 0
}
//处理状态的逻辑代码
handleMouseMove = e => {
this.setState({
x: e.clientX,
y: e.clientY
})
}
//监听鼠标移动事件
componentDidMount() {
window.addEventListener("mousemove", this.handleMouseMove)
}
//解绑事件
componentWillUnmount() {
window.removeEventListener('mousemove', this.handleMouseMove)
}
render() {
//4 渲染参数组件,同时将状态通过props传递给参数组件
return
}
}
//设置displayName
Mouse.displayName = `withMouse${getDisplayName(WrappedComponent)}`
return Mouse;
}
//displayName
function getDisplayName(WrappedComponent) {
return WrappedComponent.displayName || WrappedComponent.name || 'Component'
}
const Cat = props => (
)
//调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
const MousePosition1 = withMouse(Cat)
const Position = props => (
鼠标当前位置:(x:{props.x},y:{props.y})
)
//调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
const MousePosition2 = withMouse(Position)
class App extends React.Component {
render() {
return (
{/*渲染增强后的组件*/}
)
}
}
ReactDOM.render( , document.getElementById("root"));
问题:
添加了一个属性, 打印了props
属性没显示在props里
原因:props传递丢失
解决办法:
效果
完整代码
import React from "react";
import ReactDOM from "react-dom";
// 1 创建一个函数,名称约定以with开头
// 2 指定函数的参数,参数以大写字母开头(作为要渲染的组件)
function withMouse(WrappedComponent) {
// 3 在函数内部创建一个类组件,提供复用的状态逻辑代码,并返回
class Mouse extends React.Component {
//鼠标状态
state = {
x: 0,
y: 0
}
//处理状态的逻辑代码
handleMouseMove = e => {
this.setState({
x: e.clientX,
y: e.clientY
})
}
//监听鼠标移动事件
componentDidMount() {
window.addEventListener("mousemove", this.handleMouseMove)
}
//解绑事件
componentWillUnmount() {
window.removeEventListener('mousemove', this.handleMouseMove)
}
render() {
//4 渲染参数组件,同时将状态通过props传递给参数组件
return
}
}
return Mouse;
}
const Position = props => {
console.log(props)
return (
鼠标当前位置:(x:{props.x},y:{props.y})
)
}
//调用该高阶组件,传入要增强的组件,通过返回值拿到增强后的组件,并将其渲染到页面中
const MousePosition = withMouse(Position)
class App extends React.Component {
render() {
return (
{/*渲染增强后的组件*/}
)
}
}
ReactDOM.render( , document.getElementById("root"));