我是靠谱客的博主 复杂彩虹,最近开发中收集的这篇文章主要介绍组件源码——按钮组ButtonGroup,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

ButtonGroup组建的API如下:

属性类型说明
valuestring | number当前值
defaultValuestring | number同 value,不可控
onChangefunc选中事件,参数返回被选中的值

ButtonGroup组件主要是根据children通过findAllByType函数来找出子组件中的所有Button组件,然后利用React.cloneElement为每个Button添加ButtonGroup中的属性,比如key onClick

class ButtonGroup extends Component {

  constructor(props) {
    super(props)
    this.state = {
      value: 'value' in props ? props.value : props.defaultValue
    }
  }

  componentWillReceiveProps(nextProps) {
    'value' in nextProps && this.setState({
      value: nextProps.value
    })
  }

  render() {
    const { className, children, defaultValue, ...other } = this.props
    const items = findAllByType(children, Button)
    const buttons = items.map((item, index) => {
      if (!item) return
      return React.cloneElement(item, {
        key: index,
        type: (item.props.value == this.state.value) ? '' : 'minor',
        onClick: e => {
          e.stopPropagation()
          this.handleClick(item.props.value)
        }
      })
    })
    return (
      <div className={classnames('bfd-button-group', className)} {...other}>
        {buttons}
      </div>
    )
  }

  handleClick(value) {
    this.setState({
      value
    })
    this.props.onChange && this.props.onChange(value)
  }
}

ButtonGroup.propTypes = {
  // 当前值
  value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  // 同 value,不可控
  defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
  // 选中事件,参数返回被选中的值
  onChange: PropTypes.func,
  customProp(props) {
    if ('value' in props && !props.onChange) {
      return new Error('You provided a `value` prop without an `onClick` handler')
    }
  }
}
export default ButtonGroup
复制代码

这里需要注意的是state中value,这个属性是每个button组件的值,而不是名字,上面的value第一个作用是用来在onChange函数作为输出,第二是用来根据item.prop.vaule===this.state.value来判断当前点击的是哪一个按钮,从而让其为默认的primary按钮,而其他未点击的为minor按钮。

我们来看看封装的findAllByType函数

import React from 'react'

function isArray(v) {
  return Object.prototype.toString.call(v) === '[object Array]'
}

const getDisplayName = (Comp) => {
  if (!Comp) {
    return ''
  }
  if (typeof Comp === 'string') {
    return Comp
  }
  return Comp.displayName || Comp.name || 'Component'
}
const findAllByType = (children, type) => {
  const result = []
  let types = []
  if (isArray(type)) {
    types = type.map(t => getDisplayName(t))
  } else {
    types = [getDisplayName(type)]
  }
  React.Children.forEach(children, child => {
    const childType = child && child.type && (child.type.displayName || child.type.name)
    if (types.indexOf(childType) !== -1) {
      result.push(child)
    }
  })
  return result
}
export default findAllByType
复制代码

最后

以上就是复杂彩虹为你收集整理的组件源码——按钮组ButtonGroup的全部内容,希望文章能够帮你解决组件源码——按钮组ButtonGroup所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部