2

NutUI-React Checkbox 组件的设计与实现

 1 year ago
source link: https://jelly.jd.com/article/642e3b45decc790068698002
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
NutUI-React Checkbox 组件的设计与实现
上传日期:2023.04.06
本文主要介绍了 NutUI-React 组件库中 Checkbox 组件的实现原理,重点突出了基于 Context 实现子组件跨层级的嵌套实现,以及实现中的一些注意事项。

NutUI 是一款京东风格的移动端组件库。NutUI 目前支持 Vue 和 React技术栈,支持Taro多端适配。

期待您早日成为我们共建大军中的一员!

咚咚群号:1025679314微信群:hanyuxinting(暗号:NutUI-React)

官网GitHub: 点击进入

欢迎共建、使用!

11d36b920f7b79f2.png

为什么封装组件

在日常的项目开发过程中,会遇到很多相似的功能,在管理不同代码库的时候,也会面临重复代码的问题,组件的提炼可以解决代码粘贴复制的问题,同时通过对代码的封装复用,降低了同一功能的维护成本。

实现思路及原理

Checkbox 组件的使用场景主要分为:单独使用、多个独立使用、组合使用。而且在组合使用的场景中需要考虑 Checkbox 嵌套在其他 HTML 标签中的场景。

单独使用 Checkbox 的实现相对简单,主要根据设计的 props 来实现对应的功能,例如:checked 的对应功能是通过设置一个 state 来实现。

在组合使用的场景中,我们又封装了另外一个 CheckboxGroup 组件,通过 CheckboxGroup 组件来对 Checkbox 组件进行分组。同时为了方便的实现全选、反选等功能,需要在 CheckboxGroup 组件是上暴露 Ref,并在 Ref 挂载上处理此功能的方法。例如 CheckboxGroup 的 Ref 可以对外暴露 toggleAll、reverse 方法。

Ref 提供的方法主要借助 useImperativeHandle 实现, 代码示例如下:

useImperativeHandle(res, ()=> ({
  toggleAll(state) {

  },
  reverse() {
    const labelsForChildren = []
    React.children.map(childern, child =>{
      labelsForChildren.push(child.props.label)
    })
    const nextState = labelsForChildren.filter((childLabel) => stateForCheckboxGroup.findIndex(value) => value == childlabel) === -1
    setStateForCheckboxGroup(nextState)
  }
}))

Checkbox 的组合使用以及支持 HTML 标签嵌套主要借助 React 的 Context 来传递 props。在设计 Context 的时候,要主要只提供必需的,而不要过多的提供 props 下传。

在 CheckboxGroup 组件的 Context 中,主要提供了用于操控 state 的 check() uncheck() 方法,组合的选中状态 checkedValues,限制最大选中数量的 max

const CheckboxGroupContext =
  createContext<{
    checkedValues: string[]
    max: number | undefined
    check: (value: string) => void
    uncheck: (value: string) => void
  } | null>(null)

在调用 createContext 的时候,我们提供了 null 作为默认值,这一点比较重要。因为在 Checkbox 组件中,要同时支持 context 和 非 context 的情况。这种情况的判断,主要根据 context 的值来处理。

// checkbox.tsx
const ctx = useContext(CheckboxGroupContext)
if(ctx) {
  // 存在 ctx 的情况处理
}

在未实现 Context 支持的 Checkbox 组件的实现中,我们设计了一些内部的状态,来控制 Checkbox 的选中,禁用等功能。那在支持 Context 的情况里,我们怎么处理之前设置过的 State 呢?我们可以通过覆盖的方式来处理。

let [checked, setChecked] = useState(props.checked)

if(ctx) {
  setChecked = (checked) => {
    if(checked) ctx.check()
    else ctx.uncheck()
  }
}

上面主要介绍了 Checkbox 的几个关键的处理点,如果大家在使用 NutUI-React 过程中,发现此组件的问题可以直接通过 Issues 提问或者直接 PR 给我们。

再次期待您早日成为我们共建大军中的一员!

一起共建,一起使用!

做站内最优秀的开源组件库!

咚咚群号:1025679314赶紧加入我们吧!!

一种更优雅的 Vue 组件库使用方式:自动按需引入

NUTUI-React电梯楼层组件的设计与实现

NutUI-React 适配 Taro 的实现

基于 Leo+NutUI 的移动端项目模板实践

NutUI-React Input输入框的使用指南

NUTUI-React 数字滚动组件的设计与实现

NutUI-React 组件库的动态主题探索

NutUI 4.0 正式发布!

2022 倒带-NutUI

京东 React 组件库支持小程序开发了

NutUI 京东小程序发布了!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK