编写更好的 React 组件的 3 个技巧
摆脱代码异味。
这次冲刺我的任务之一是实现一个非常复杂的新功能,其中包含动态问题以及在问题之间跳转的逻辑。我预计这项任务需要 5 个小时,唯一需要做的改动就是在当前发送时添加一个额外的验证。
我一直在思考这个问题,直到我看到需要更新的组件。这个组件有 300 多行代码,其中一段 JSX 标记代码大概有 150 行,而且逻辑……这个组件里有很多 setState 和 useEffect,并且有很多依赖。
我既惊讶又羞愧,因为我写了这段代码,结果它变成了一个我完全看不懂的庞然大物。你知道,就像你盯着屏幕十五分钟思考这个函数到底是干什么用的那种感觉。
代码异味
你可能之前听说过这个,如果没有,代码异味实际上就是我之前描述的那样。它表明你的代码存在缺陷,它们不是 Bug,因为 Web 应用运行良好,但它会增加未来出现 Bug 或故障的风险。
那么,如何处理这样的代码?
我按照这些提示重构了我之前描述的组件,希望它也能对您有所帮助。
使用 useReducer 代替 useState
我提到过这个组件有多个useState
,这很难阅读,因为我必须查找所有内容setState
才能知道组件的哪个部分更新了某个状态。
是的,我知道,看起来很糟糕。如果你最终的代码是这样的,你必须考虑重构。很多状态都是相关的,所以我可以创建一个 Reducer 来处理这种表单可能出现的情况。
这也增加了你对这些 Reducer Action 的影响的了解。当你将逻辑分离到 Action 中时,你就能知道哪些 Action 会影响状态的某些字段。这能让你更好地控制状态,从而更容易地实现新功能。
分离逻辑。
在这个例子中,我需要从 graphql 上的 API 获取一些数据。我使用了 apollo 和@apollo/react-hooks
。获取数据后,我需要更新一些状态。与其在同一个组件中获取数据,不如创建一个自定义钩子,只返回我需要的状态。
如果我需要使用变异或添加额外的查询,我也可以在这个钩子中写入该逻辑。
我建议你在数据获取时遵循关注点分离原则,可以为数据相关的逻辑创建一个单独的文件,并只返回将在组件中渲染的状态。这也适用于你的 UI,在需要时创建一个展示组件,可以让你更好地理解应用的工作原理。
将其分成更小的块
我写的怪物组件的 UI 代码超过 100 行。代码量很大div
,div
我花了两分钟多才明白自己到底在做什么。整个界面都div
充斥着条件渲染,我得往下滚动好一会儿才能知道哪里结束了。
看看上面的代码。那个currentForm
布尔值包裹了一大段 JSX 标记。如果我们把这个 UI 移到另一个组件中,它的可读性会更高。
好多了,我可以将这个大组件拆分成更小的组件,这样下一个人看到这段代码就会确切地知道所有内容在哪里。
结论
编写代码没有完美的方法,不同的团队遵循不同的模式,但如果你和我看到那段代码时有同样的感受,那么它可能也需要重构。请记住:
-
如果您正在使用多个
useState
,请尝试将其更改为useReducer
。这样,您将能够更好地控制并更全面地了解每个操作中状态的变化。 -
分离可复用的逻辑。您可以创建自定义钩子来获取数据,或者创建可在应用程序其他部分使用的实用函数。
-
将组件拆分成更小的部分。将 JSX 标记提取到不同的组件中,以提高代码的可读性。