前提:组件复用是复用什么?
复用state和操作state的方法
两种复用方式:
1、render props
class Mouse extends ReactComponent {
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() {
return (
this.props.renderContent(this.state)
)
}
}
Mouse.propTypes = {
children: PropTtpes.func.isRequired
}
class App extends ReactComponent {
render() {
return (
<Mouse renderContent={(mouseState) => {
return (
<p>鼠标当前位置:{mouseState.x} {mouseState.y}</p>
)
}} />
<Mouse renderContent={(mouseState) => {
return (
<img src='' alt='picture' style={{position:'absolute',top:mouseState.y,left:mouseState.x}}/>
}} />
)
}
}
//children 写法,推荐!!!
class Mouse extends ReactComponent {
...
render() {
return (
this.props.children(this.state)
)
}
}
class App extends ReactComponent {
render() {
return (
<div>
<Mouse>
{mouseState => (
<p>鼠标当前位置:{mouseState.x} {mouseState.y}</p>
)}
</Mouse>
<Mouse>
{mouseState => (
<img src='' alt='picture' style={{ position: 'absolute', top: mouseState.y, left: mouseState.x }} />
)}
</Mouse>
</div>
)
}
}
2、高阶组件
//定义高阶组件 以with开头!参数以大写字母开头!
const withMouse = (WrappedCpmponent)=>{
class Mouse extends ReactComponent {
state = {
x: 0,
y: 0
}
componentDidMount() {
window.addEventListener('mousemove', (e) => {
this.setState({
x: e.clientX,
y: e.clientY
})
})
}
render() {
return (
<WrappedCpmponent {...this.state} {...this.props}></WrappedCpmponent>
)
}
}
Mouse.displayName = `Mouse${getDisplayName(WrappedCpmponent)}`
return Mouse
}
const getDisplayName = function (WrappedCpmponent){
return WrappedCpmponent.displayName || WrappedCpmponent.name || 'defaultName'
}
//定义两个函数组件
const PositionMouse = props => (
<p>鼠标的位置是:{props.x} {props.y}</p>
)
const ImgMouse = props => (
<img src='' alt='picture' style={{ position: 'absolute', top: props.y, left: props.x }} />
)
//调用withMouse包裹
const PositionComponent = withMouse(PositionMouse)
const ImgComponent = withMouse(ImgMouse)
class App extends ReactComponent {
render() {
return (
<div>
<PositionComponent a={1}/>
<ImgComponent/>
</div>
)
}
}