1. 组件复用的方式:
- render props模式
- 高阶组件(HOC)
注意:以上两种方式不是新的API,而是演化而成的一种固定模式(写法)
2. render props模式
- 思路:将要复用的state和操作state的方法封装在一个组件里面(在组件中提供复用的状态逻辑代码,即状态和操作状态的方法)
- 这时,我们就要思考两个问题:(1)状态是组件内部私有的,那么如何在复用组件的时候拿到组件内部的state呢?----> 可以在使用组件的时候,添加一个值为函数的props,那么就可以通过函数参数来获取组件内部的state。(2)复用组件时,需要渲染的UI结构会不一样,那么怎么在复用组件时实现渲染任意的UI呢?----->将函数的返回值作为要渲染的UI
- 注意:复用的组件并没有渲染任何的UI结构,而且通过函数的返回值来渲染的。
- 以下通过一个简单的例子来演示使用render props模式实现的组件复用(一个效果是随着鼠标移动,获取鼠标的位置,另一个效果是图片随着鼠标移动而移动,这两个效果的实现都要获取x和y坐标,所以可以考虑用组件的复用来实现)
Mouse组件(要复用的组件)
import React from "react";
class Mouse extends React.Component {
//复用的state
state = {
x: 0,
y: 0
}
//操作state的方法
handleMouseMove = e => {
this.setState({
x: e.clientX,
y: e.clientY
})
}
//监听鼠标移动事件
componentDidMount() {
window.addEventListener("mousemove", this.handleMouseMove)
}
render(){
return this.props.render(this.state) //通过函数参数暴露组件内部的状态
}
}
export default Mouse;
Mouse_Tree组件(复用Mouse组件的组件)
import React from "react";
import Mouse from "./Mouse.js";
import img from "./images/tree.PNG"
class Mouse_Cat extends React.Component {
render(){
return(
<div>
<Mouse render={ mouse => {
return(
<p>X坐标为:{mouse.x} Y坐标为:{mouse.y}</p>
)
}}/>
<Mouse render={ mouse => {
return(
<img src={img} alt="树" style={{
position: 'absolute',
top: mouse.y,
left: mouse.x
}}/>
)
}}/>
</div>
)
}
}
export default Mouse_Cat;
以上则是组件复用的一个简单应用
- 另外注意,这个虽然叫做render props模式,但是所添加的props不一定需要命名为render,可以是任意名称的props。在我们的实际应用中,更推荐使用children代替render属性,可以把以上代码做如下修改:
//Mouse_Tree组件内部 {/* <Mouse render={ mouse => { return( <p>X坐标为:{mouse.x} Y坐标为:{mouse.y}</p> ) }}/> */} <Mouse> { mouse => { return( <p>X坐标为:{mouse.x} Y坐标为:{mouse.y}</p> ) } } </Mouse> //Mouse组件内部 render(){ // return this.props.render(this.state) //通过函数参数暴露组件内部的状态 return this.props.children(this.state); }