这里写目录标题
一、Render props
1、场景
import React, { PureComponent } from 'react'
import "./style.css"
export default class MovablePanel extends PureComponent {
state = {
x: 0,
y: 0
}
divRef = React.createRef()
handleMouseMove = e => {
//更新x和y的值
const { left, top } = this.divRef.current.getBoundingClientRect();
const x = e.clientX - left;
const y = e.clientY - top;
this.setState({
x,
y
});
}
render() {
return (
<div ref={this.divRef} className="point" onMouseMove={this.handleMouseMove}>
<div style={{
width: 100,
height: 100,
background: "#008c8c",
position: "absolute",
left: this.state.x - 50,
top: this.state.y - 50
}}>
</div>
</div>
)
}
}
import React, { PureComponent } from 'react'
import "./style.css"
export default class ShowMousePoint extends PureComponent {
state = {
x: 0,
y: 0
}
divRef = React.createRef()
handleMouseMove = e => {
//更新x和y的值
const { left, top } = this.divRef.current.getBoundingClientRect();
const x = e.clientX - left;
const y = e.clientY - top;
this.setState({
x,
y
});
}
render() {
return (
<div ref={this.divRef} className="point" onMouseMove={this.handleMouseMove}>
<h2>
鼠标x:{parseInt(this.state.x)},
鼠标y:{parseInt(this.state.y)}
</h2>
</div>
)
}
}
这里两个组件其实基本功能一直,都是获取当前鼠标的位置从而显示需要的页面,但是这样的组件明显代码冗余,那么我们如何进行解决呢?
- HOC高阶组件
- render props
2、render props
//MouseListener
import React, { PureComponent } from 'react'
import "./style.css"
/**
* 该组件用于监听鼠标的变化
*/
export default class MouseListener extends PureComponent {
state = {
x: 0,
y: 0
}
divRef = React.createRef()
handleMouseMove = e => {
//更新x和y的值
const { left, top } = this.divRef.current.getBoundingClientRect();
const x = e.clientX - left;
const y = e.clientY - top;
this.setState({
x,
y
});
}
render() {
return (
<div ref={this.divRef} className="point" onMouseMove={this.handleMouseMove}>
{this.props.children ? this.props.children(this.state) : "默认值"}
</div>
)
}
}
import MouseListener from "./MouseListener";
import React from 'react'
const renderPoint = mouse => <>横坐标:{mouse.x},纵坐标:{mouse.y}</>
const renderDiv = mouse => <>
<div style={{
width: 100,
height: 100,
background: "#008c8c",
position: "absolute",
left: mouse.x - 50,
top: mouse.y - 50
}}>
</div>
</>
export default function Test() {
return (
<div>
<MouseListener>
{renderPoint}
</MouseListener>
<MouseListener>
{renderDiv}
</MouseListener>
</div>
)
}
通过MouseListener
组件专门去获取当前鼠标位置,然后我们只需要传入我们需要的页面组件即可,这里就应用到了react传递元素内容children
,并且通过children
传递页面组件需要的参数。
那为什么要交render props呢?因为我们通常是以下写法,因为是在render中传递属性,所以叫render props
import React, { PureComponent } from 'react'
import "./style.css"
/**
* 该组件用于监听鼠标的变化
*/
export default class MouseListener extends PureComponent {
state = {
x: 0,
y: 0
}
divRef = React.createRef()
handleMouseMove = e => {
//更新x和y的值
const { left, top } = this.divRef.current.getBoundingClientRect();
const x = e.clientX - left;
const y = e.clientY - top;
this.setState({
x,
y
});
}
render() {
return (
<div ref={this.divRef} className="point" onMouseMove={this.handleMouseMove}>
{this.props.render ? this.props.render(this.state) : "默认值"}
</div>
)
}
}
import MouseListener from "./MouseListener";
import React from 'react'
const renderPoint = mouse => <>横坐标:{mouse.x},纵坐标:{mouse.y}</>
const renderDiv = mouse => <>
<div style={{
width: 100,
height: 100,
background: "#008c8c",
position: "absolute",
left: mouse.x - 50,
top: mouse.y - 50
}}>
</div>
</>
export default function Test() {
return (
<div>
<MouseListener render={renderPoint} />
<MouseListener render={renderDiv} />
</div>
)
}
有时候,某些组件的各种功能及其处理逻辑几乎完全相同,只是显示的界面不一样,建议下面的方式认选其一来解决重复代码的问题(横切关注点)
- render props
- 某个组件,需要某个属性
- 该属性是一个函数,函数的返回值用于渲染
- 函数的参数会传递为需要的数据
- 注意纯组件的属性(尽量避免每次传递的render props的地址不一致)
- 通常该属性的名字叫做render
- HOC
博主开始运营自己的公众号啦,感兴趣的可以关注“飞羽逐星”微信公众号哦,拿起手机就能阅读感兴趣的博客啦!