-
术语 “render prop” 是指一种简单的技术,用于使用一个值为函数的 prop 在 React 组件之间的代码共享;
-
在 React 中,常见有两种方式来进行横切关注点的抽离:
- 高阶组件(HOC)
- Render Props
Render Props 概念
-
Render Props 是 React 中一种常见的组件复用模式,用于将组件的渲染逻辑与组件的状态逻辑分离开来;Render Props 模式允许一个组件通过在 props 中传递一个函数来控制另一个组件的渲染;
-
Render Props 实际上并非什么新语法,而是指一种在 React 组件之间使用一个值为函数的 prop 共享代码的简单技术;
Render Props 优点
-
组件复用
:通过将渲染逻辑封装在一个函数中,多个组件可以共享同一个渲染逻辑,避免代码冗余; -
灵活性
:Render Props 模式允许父组件决定子组件的渲染方式,子组件可以根据父组件传递的函数来自定义渲染内容,提供了更大的灵活性和可定制性; -
数据共享
:通过 Render Props 父组件可以将自己的状态或其他数据传递给子组件,实现了数据共享的目的;
Render Props 案例
/*
* index.js
*/
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
ReactDOM.render(<App />, document.getElementById("root"));
/*
* App.js
*/
import React from "react";
import Test from "./components/Test";
export default function App() {
return <Test />;
}
/*
* Test.js
*/
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>
);
}
/*
* MouseListener.js
*/
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>
);
}
}
HOC 案例
/*
* Test.js
*/
import withMouseListener from "./withMouseListener";
import React from "react";
function Point(props) {
return (
<>
横坐标:{props.x},纵坐标:{props.y}
</>
);
}
function MoveDiv(props) {
return (
<div
style={{
width: 100,
height: 100,
background: "#008c8c",
position: "absolute",
left: props.x - 50,
top: props.y - 50,
}}
></div>
);
}
const MousePoint = withMouseListener(Point);
const MouseDiv = withMouseListener(MoveDiv);
export default function Test() {
return (
<div>
<MousePoint />
<MouseDiv />
</div>
);
}
/*
* withMouseListener.js
*/
import React, { PureComponent } from "react";
import "./style.css";
export default function withMouseListener(Comp) {
return 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}
>
<Comp {...this.props} x={this.state.x} y={this.state.y} />
</div>
);
}
};
}
Render Props VS HOC
-
一般来讲,Render Props 应用于组件之间功能逻辑完全相同,仅仅是渲染的视图不同;这个时候可以通过 Render Props 来指定要渲染的视图是什么;
-
而 HOC 一般是抽离部分公共逻辑,也就是说组件之间有一部分逻辑相同,但是各自也有自己独有的逻辑,那么这个时候使用 HOC 比较合适,可以在原有的组件的基础上做一个增强处理;
React✍️ PureComponent、React.memo
上一篇