组件

组件的定义、传参(props)、数据响应(State)、生命周期(liefCycle)、事件处理(Events)

  • 任何 MVVM Js框架都离不开组件的概念,组件的使用、扩展、复用、独立性,构成了组件使用的优越及带来的便利
  • 下面梳理了一个组件的定义,传参、数据响应,生命周期、事件处理的全过程

定义组件

  • React 定义组件最简单的方式是使用函数
  • 亦可以使用 ES6 class 来继承、定义组件
  • 组件的定义、使用,首字母都必须大写
  • Props 用来传递参数,要注意:Props 不能被更改
function Hello (props) {
  return <h1>Hello, {props.name}</h1>
}

class Hello extends React.Component {
  render () {
    return <h1>Hello, {this.props.name}</h1>
  }
}

复杂组件

class Welcome extends React.Component {
  constructor (props) {       // 尽管 constructor 构造函数不是每次都必要的,但为了实现组件的参数传递,props 必不可少
    super(props)              // 注意 props 的传递及 super 函数的使用,constructor 必须搭配 super
    this.state = {            // state 是用来实现数据监听的,所有使用this.state.xx 的变量将在数据变化时被实时渲染响应
      school: '',             // 注意的是 state 值的变化不应用 this.state.xx = yy的方法,而是使用
      city: ''                // this.setState({key: value})来实现
    }
  }

  componentDidMount () {       // 生命周期钩子:DidMount 用于组件第一次加载到 DOM 中,挂载
    this.setState({
      school: 'QingHua',
      city: 'BeiJing'
    })
  }

  componentWillMount () {      // 生命周期钩子:Unmount 用于组件被 DOM 移除,即卸载
    this.setState({
      school: '',
      city: ''
    })
  }

  setSchool = (e) => {        // 注意到,事件的定义是采用箭头函数定义的,关于这个问题,可以查看下面的提示
    this.setState({
      school: e.target.value
    })
  }

  resetSchool (school, e) {   // 注意,事件的参数,传参是怎么获取和设定的
    this.setState({
      school: school
    })
  }

  render () {  // 每一个组件,必不可少的 render 函数渲染主体,且必定返回一个 jsx 对象
    return (
      <div className={'react-comp'}>
        <input type="text" value={this.state.school} onChange={this.setSchool}/>
        <div>This is <b>{this.state.school}</b> : Welcome new student: <b>{this.props.student}</b></div>
        <button onClick={this.resetSchool.bind(this, 'QingHua')}>reset</button>     {/*函数的传递参数,一般使用 .bind(this. params) 来进行传递*/}
        {/*props是通过属性传递*/}
      </div>
    )
  }
}

注意事项

  • state 不能直接使用 this.state.xx = yy 来进行更新,这样不会渲染组件
  • 多个setState() 将会被合并成一个来调用,以此提高性能
  • Props 是只读的,意味着它不能用来修改,这一点跟 vue 一致
  • 由于 this.props 与this.state 可能是异步更新的,所以不能依靠它们来计算下一个状态,例如以下代码
this.setState({
  counter: this.state.counter + this.props.increment
})
  • 因为此时,counter 跟 increment 可能还在等待更新中,所以应采用下面这种方法
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
})
// 或
this.setState(function (prevState, props) {
  return {
    counter: prevState.counter + props.increment
  }
})
  • 在 react 中的事件绑定,如果直接定义函数并且调用,是取不到 this 指针对像的,如下
  {
    onClickEvt () {
      this.setState(...)      // 此时报错,this 是 undefined
    }
    render () {
      return (<div onClick={onClickEvt}></div>)
    }
  }
{
  constructor(){
    this.onClickEvt = this.onClickEvt.bind(this)      // 1. 在构造函数中绑定 this,常规操作,但较为麻烦
  }

  onClickEvt = () => {}                               // 2. 使用箭头函数,需要 babel 转义

  render () {
    return (
      <div onClick={(e) => this.onClickEvt(e)}</div>    // 3. 使用函数包裹,这种用法如果这个回调函数作为一个属性值传入低阶组件(即 props 使用)可能会额外地进行重新渲染,导致性能问题
    )
  }
}
  • 父组件或子组件都不能知道某个组件是有状态还是无状态,并且它们不应该关心某组件是被定义为一个函数还是一个类
  • 这一点跟高内聚、低耦合的概念很相似,组件只依据传入的参数进行业务执行、并根据规则对外界反应
  • 而不是通过一些属性暴露本身的状态
  • 强调的是:数据自顶向下流动

results matching ""

    No results matching ""