提高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}/>}/>
    )
  }
}

 

posted @ 2019-11-20 13:43  Lyra李  阅读(827)  评论(0编辑  收藏  举报