render-props
React组件复用概述
处理方式:复用相似的功能(联想函数封装)
复用:1.state 2.操作state的方法(组件状态逻辑)
两种方式:1.render props模式 2.高阶组件(HOC)
注意:这两种方式不是新的API,而是利用React自身特点的编码技巧,演化而成的固定模式(写法)
render props模式
思路分析
思路:将要复用的state和操作state的方法封装到一个组件中
在使用组件时,添加一个值为函数的prop,通过函数参数来获取(需要组件内部实现)
使用该函数的返回值作为要渲染的UI内容(需要组件内部实现)
使用步骤
1.创建Mouse组件,在组件中提供复用的逻辑状态代码(1.状态 2.操作状态的方法)
2.将要复用的状态作为props.render(state)方法的参数,暴露到组件外部
3.使用props.render()的返回值作为要渲染的内容
//1. 导入react import React from 'react'; import ReactDOM from 'react-dom'; /* render props 模式 */ //创建Mouse组件 class Mouse extends React.Component { //鼠标位置state state = { x:0, y:0 } //鼠标移动事件的事件处理程序 handelMouseMove = e => { this.setState({ x: e.clientX, y: e.clientY }) } //监听鼠标移动事件 componentDidMount() { window.addEventListener('mousemove', this.handelMouseMove) } render() { // return null return this.props.render(this.state) } } class App extends React.Component { render() { return ( <div> <h1>render props 模式</h1> <Mouse render={(mouse) => { return ( <p> 鼠标位置:{mouse.x} {mouse.y} </p> ) }} /> </div> ) } } ReactDOM.render(<App />, document.getElementById('root'))
Mouse组件的复用
//1. 导入react import React from 'react'; import ReactDOM from 'react-dom'; /* render props 模式 */ //导入图片资源 import img from './images/cat.jpg' //创建Mouse组件 class Mouse extends React.Component { //鼠标位置state state = { x:0, y:0 } //鼠标移动事件的事件处理程序 handelMouseMove = e => { this.setState({ x: e.clientX, y: e.clientY }) } //监听鼠标移动事件 componentDidMount() { window.addEventListener('mousemove', this.handelMouseMove) } render() { // return null return this.props.render(this.state) } } class App extends React.Component { render() { return ( <div> <h1>render props 模式</h1> <Mouse render={(mouse) => { return ( <p> 鼠标位置:{mouse.x} {mouse.y} </p> ) }} /> {/* 猫捉老鼠 */} <Mouse render={mouse => { return <img src={img} alt="猫" style={{ position:'absolute', top:mouse.y, left:mouse.x }}></img> }} /> </div> ) } } ReactDOM.render(<App />, document.getElementById('root'))
推荐使用children代替render属性
<Mouse>
{ ({x, y}) => <p>鼠标的位置是 {x}, {y}</p> }
</Mouse>
//组件内部
this.props.children(this.state)
//1. 导入react
import React from 'react';
import ReactDOM from 'react-dom';
/*
render props 模式
*/
//导入图片资源
import img from './images/cat.jpg'
//创建Mouse组件
class Mouse extends React.Component {
//鼠标位置state
state = {
x:0,
y:0
}
//鼠标移动事件的事件处理程序
handelMouseMove = e => {
this.setState({
x: e.clientX,
y: e.clientY
})
}
//监听鼠标移动事件
componentDidMount() {
window.addEventListener('mousemove', this.handelMouseMove)
}
render() {
// return null
// return this.props.render(this.state)
return this.props.children(this.state)
}
}
class App extends React.Component {
render() {
return (
<div>
<h1>render props 模式</h1>
{/* <Mouse render={(mouse) => {
return (
<p>
鼠标位置:{mouse.x} {mouse.y}
</p>
)
}} /> */}
<Mouse>
{
mouse => {
return (
<p>
鼠标位置:{mouse.x} {mouse.y}
</p>
)
}
}
</Mouse>
<Mouse>
{
mouse => {
return (
<img src={img} alt="猫" style={{
position:'absolute',
top:mouse.y,
left:mouse.x
}}></img>
)
}
}
</Mouse>
{/* 猫捉老鼠 */}
{/* <Mouse render={mouse => {
return <img src={img} alt="猫" style={{
position:'absolute',
top:mouse.y,
left:mouse.x
}}></img>
}} /> */}
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'))
render-props 优化
1.给render props 模式添加props校验
2.应该在组件卸载时解除mousemove事件绑定
// import PropTypes from 'prop-types'
//添加props校验
Mouse.proTypes = {
children:PropTypes.func.isRequired
}
//在组件卸载时移除事件绑定
componentWillUnmount() {
window.removeEventListener('mousemove', this.handelMouseMove)
}
浙公网安备 33010602011771号