react组件开发—ES6父子组件间的通信以及子组件设计模式

#1

做react组件开发的人,一般有2种。
1、使用typescript的人;
2、使用ES5/6的人。

typescript语法糖好处在于多了个interface,这样就可以通过interface来定义API接口,可是还有很多同学用ES6,包括我自己,那么,又该通过什么办法来封装组件,保存父子组件之间的通信呢?

下面通过一个最基本的选择框的例子来看看
API文档:
selectId: 当前组件的id
value:组件的文本

组件提供的功能:
1、单选组件
2、保存选中的状态
3、外部可以读取到组件选中的值

效果图:

select.js(子组件)

import React, { Component } from 'react';
import classNames from 'classnames';

export class select extends Component {

constructor(props) {
    super(props)
    //绑定getValue到当前的类
    this.getValue = this.getValue.bind(this)
}

componentWillMount() {
    const { selectId } = this.props
    //定义一个数据结构保存选择的值和id,{selectId: ' ', value: ' '}
    组件渲染前先设置组件id到state
    this.setState({
        select: {selectId: selectId}
    })
}

render() {
    //传入2个参数
    const { selectId, value } = this.props
    const { select } = this.state
    let active = classNames({
              "select-option": true,
               selectActive: select.value === value ? true : false
          })
    return (  
               <span                                                                  
                        className={active}
                        onClick={() => this.saveState(value)}
                >
                 {value}
                </span>         
    )
}
// 保存点击选中状态(单选),如果你想把这个组件做成支持单选和多选的2种,那么需要加多一个API为type,
//组件内部通过switch来控制type返回function,state的数据结构要改成[{}, {}, {}]的形式
saveState(value) {
    const { select } = this.state
     if (select.value === value) {
         delete select.value
     } else {
         select.value = value
     }
     this.setState({...select})
}
 //提供选中的数据给外部读取
getValue() {
    return this.state.select
}

}

container.js(父容器)

import React, { Component } from 'react'

import { Select } from './select'

export default class Container extends Component {
    constructor(props) {
	super(props)
	this.nextClick = this.nextClick.bind(this)
}

    nextClick() {
         //点击事件,获取子组件选中的值
         console.log(this.refs.select.getValue())
         if (!this.refs.select.getValue().value) {
             console.log("你忘了选中我!")
         } else {
             console.log("你选中我!可以进行下一步操作了!可以将这些值保存到reducer或者浏览器缓存,或者当做ajax的参数都行。")
         }
    }

    render() {
        return (
             <div>
                     <Select ref="select" selectId="" value="" />
                     <a onClick={() = this.nextClick()}>点击我就能读到select的值啦</a>
             </div>
        ) 
    }
}

更多功能根据自己业务需求去添加,包括事件API,各种回调等。