为什么要跟踪onChange?
因为源码庞杂同时依赖复杂。我们需要聚焦一个细小的点来顺藤摸瓜,才有可能有收获。要不然容易迷失在茫茫源码中。
那为什么是onChange?
因为onChange涉及对数据的处理,这个才是组件的核心逻辑。
如何跟踪onChange?
以NextUI为例我们分为这几步来跟踪:
-
我们先看NextUI组件文档,为了确认onChange是哪个组件的参数。:
如上图发现onChange事件在Checkbox Group上,而不是在checkbox上,这缩小了我们检索范围
-
打开Checkbox Group的源码,找到接收参数的地方,开始跟踪:
const CheckboxGroup = React.forwardRef<HTMLDivElement, CheckboxGroupProps>( ( { color, labelColor, disabled, size, label, children, readOnly, row, ...props //很可能onChange藏在这里 }, ref: React.Ref<HTMLDivElement | null> ) => {因为onChange是用户传入的参数,一定会传参传入。 这里没有,很可能在props里面藏着
那我们鼠标悬浮在props上:
果然在!
-
根据上一步开始跟踪 props。
发现:props 先传给
useCheckboxGroupState然后传给useCheckboxGroup -
开始分析
useCheckboxGroupState和useCheckboxGroup
对onChange做了哪些加工?
根据上一小结,onChange通过props传给useCheckboxGroupState 和useCheckboxGroup 。所以这一节通过分析useCheckboxGroupState 和useCheckboxGroup 来找到对onChange做了哪些加工?
-
分析
useCheckboxGroupState的输入,输出。const state = useCheckboxGroupState({ ...props, isDisabled: disabled, isReadOnly: readOnly });输入,基本都是用户传入的参数:
{ ...props, isDisabled: disabled, isReadOnly: readOnly }
输出:返回value的同时,还返回很多关于value的增删改查的函数。
export interface CheckboxGroupState { /** Current selected values. */ readonly value: readonly string[], /** Whether the checkbox group is disabled. */ readonly isDisabled: boolean, /** Whether the checkbox group is read only. */ readonly isReadOnly: boolean, /** Returns whether the given value is selected. */ isSelected(value: string): boolean, /** Sets the selected values. */ setValue(value: string[]): void, /** Adds a value to the set of selected values. */ addValue(value: string): void, /** Removes a value from the set of selected values. */ removeValue(value: string): void, /** Toggles a value in the set of selected values. */ toggleValue(value: string): void } -
分析
useCheckboxGroup:const { groupProps } = useCheckboxGroup( { ...props, 'aria-label': props['aria-label'] || (typeof label === 'string' ? label : undefined), isDisabled: disabled, isReadOnly: readOnly }, state );
输入,用户传入的参数,和value,以及value增删改查的函数:
( { ...props, 'aria-label': props['aria-label'] || (typeof label === 'string' ? label : undefined), isDisabled: disabled, isReadOnly: readOnly }, state )
输出:groupProps 也就是传给div的参数, 也传给子组件
<StyledCheckboxGroup ref={domRef} size={size} {...mergeProps(props, groupProps)} > ··· //这里将value,value相关的函数传给子组件 <CheckboxContext.Provider value={providerValue}> {children} </CheckboxContext.Provider> -
总结
收获
通过将value的onChange传入useCheckbox,得到value的增删改查函数: 这样有几个好处:
- 提供的增删该查函数,将简化checkbox里面的代码逻辑
- 简化checkbox代码逻辑的同时,增加代码可读性
- 将value的onChange函数变为value的增删改查函数的过程中,可以增加对异常情况的检查。能增加代码的鲁棒性