概述
ButtonGroup组建的API如下:
属性 | 类型 | 说明 |
---|---|---|
value | string | number | 当前值 |
defaultValue | string | number | 同 value,不可控 |
onChange | func | 选中事件,参数返回被选中的值 |
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所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复