提高React组件的复用性
1. 使用props属性和组合
1. props.children
在需要自定义内容的地方渲染props.children
function Dialog(props) { //通用组件 return ( <div> <h1 className="dialog-title">{props.title}</h1> <p className="dialog-message"> {props.message} </p> { props.children //在组件最后用户可以自定义添加内容 } </div> ) } class SignUpDialog extends React.Component { constructor(props) { super(props); this.state={ loginName: '' } } handleChange = (e) => { this.setState({ loginName: e.target.value }) } render() { return ( <Dialog title="welcom" message="Thank you for visiting our spacecraft!" > <input type="text" value={this.state.loginName} onChange={this.handleChange} /> <button> 注册 </button> </Dialog> ) } }
2. 将组件作为变量传递到另一个组件
function Dialog(props) { //通用组件 return ( <div> { props.selfDefine || <h1 className="dialog-title">{props.title}</h1> } <p className="dialog-message"> {props.message} </p> </div> ) } class SignUpDialog extends React.Component { render() { const h2 = <h2>这是自定义的标题</h2>; return ( <Dialog title="welcom" message="Thank you for visiting our spacecraft!" selfDefine={h2} /> ) } }
2. 高阶组件
3. Render props
统指属性值是函数的属性,返回值用于指定渲染内容。
当将函数作为属性时,如果函数直接定义在属性上,每次render都会生成一个新的函数;会导致props始终处于变化状态。这时和PureComponent冲突。 解决办法: 1)将PureComponent改为Component 2) 函数传入函数实例。在外部定义好函数后传入
属性名称可以随意指定,children也可以是一个返回渲染内容的函数。
这个属性很多时候可以替代高阶组件;也可以和高阶组件一起使用。
import img from './cat.png'; import './index.css'; class Cat extends React.Component { render() { const { x, y} = this.props.mouse; return ( <img style={{position: 'absolute', top:y, left: x }} src={img} /> ) } } // 公用组件;相当于高阶组件的公共部分 class Mouse extends React.Component{ constructor(props) { super(props); this.state = { x: 50, y: 0 } } handleMouseOver = (e) => { this.setState({ x: e.clientX, y: e.clientY }) } render() { return ( <div style={{height: '100%'}} onMouseMove={this.handleMouseOver}> <h1>查看鼠标</h1> {this.props.renderMouse(this.state)} </div> ) } } class MouseTracker extends React.Component { render() { return( <Mouse renderMouse={(mouse) => <Cat mouse={mouse}/>}/> ) } }