作为开源维护者,你通常希望别人通过提issue或PR来反馈问题。但最近,我发现自己维护的React漫画阅读器组件react-comic-viewer被三个人分叉了——他们没提过任何issue,却用代码告诉我:我的组件设计有问题。
在npm上闲逛时,我注意到有三个包几乎用了和我一样的名字,描述和仓库地址都指向我的项目。这三个分叉版本都没有提交过issue或PR,但其中一个分叉持续维护了将近一年,版本号甚至跑到了0.6.3,而当时我的版本还停留在0.3.5。
分叉者的提交记录,比issue更有价值
我仔细读了他们的diff。说实话,这些代码比任何issue都有用。提交信息本身就把问题说清楚了:有人修了Sass样式问题,有人修了className处理,还有一个我四年来从未修复的controlled.tsx问题。
看他们的示例代码,他们期望组件支持这样的用法:传入currentPage和onChangedCurrentPage,让父组件完全控制当前页。而我的组件实际接受的是initialCurrentPage——这个"initial"前缀就是问题的根源。
组件接管了状态,就再也交不出去
我的组件会接受一个起始页,然后永远自己管理这个状态。对演示来说没问题,但对真实应用来说很糟糕:你没法从目录跳转到指定页,没法把当前页同步到URL,也没法在章节需要购买时拦截翻页动作。这些场景都需要父组件掌控状态,但我的组件从来没给过这个机会。
这就是标准的受控/非受控模式,没什么高深的。但让我尴尬的是,我花了很长时间才意识到这个问题。最终我写了一个useControllableState的hook,让组件既能自己管理状态,也能把控制权交给父组件。
这件事让我反思:有时候,分叉者的代码比客气的issue更有说服力。他们用行动告诉我,用户真正需要的是什么。
热门跟贴