- 🌱 I’m currently learning Nextjs,Three.js and Web3
- 📫 How to reach me: [email protected]
- 😄 my blog: juejin
viewerw / blog Goto Github PK
View Code? Open in Web Editor NEWFrontend blog
Frontend blog
组件是构建React应用的基石,良好的组件设计,可以最大程度的发挥React的性能优势,也方便日后代码的维护与迭代。很多新手刚刚接触 React 时,不懂得合理的拆分设计组件,总是习惯性地写一个很庞大的 Page 组件,然后将所有的元素,所有的业务、交互逻辑写在一起。我相信很多人看过这样的代码,可能也曾经写过这样的代码,那么,这样写代码有什么问题呢?我们为什么要细粒度的拆分组件?如何去合理的设计组件?带着这些问题,我们一起去谈一谈 React 中的组件设计。
基于 React 框架的特性,以及编码原则,我们从以下三点去分析组件拆分的必要性:
state
,useEffect
,handleFuncs
,看到这样的代码,谁不迷糊,即使产品只提了一个很小的功能改动,你都很可能要阅读整个文件代码,梳理逻辑,小心谨慎以免翻车。反之,如果这样的巨石组件被合理的按照业务逻辑、功能模块拆分成多个细小的单一职责的组件,组件树结构清晰,代码阅读也会通畅,任何一个功能的改动只需要定位到相关的组件即可,降低了心智负担,提高了工作效率。state
的变化会触发组件的重新渲染,如果整个页面只有一个组件,那么这个组件内部就包含了大量的state
,任何一个state
的变化,都会这个巨石组件的重新渲染。反之,如果这个巨石组件被合理的拆分成多个子组件,那么状态也被合理的分散到各个子组件内部,子组件内部的state
变化只会导致当前这个子组件的渲染,不会影响其他子组件。在 React 中合理的拆分巨石组件(也叫做大型、巨型组件),可以帮助我们构建更具有可维护性和可扩展性的应用程序,巨石组件的拆分,应该遵循以下几点:
React 官方文档中Thinking in React一文介绍了如何构建React 组件:
上面我们提到了构造组件的两种方式,分别是自上而下和自下而上,这两种方式代表了构建组件的两种不同的心智模型,随着组件的扩展,两种设计方式将会产生不同的结果。
自上而下的构建方式,是大多数开发者在构建组件时最常用的心智模型,因为它是符合直觉的、直观的。这种方式也可以相对容易的快速构建组件。
我们在设计稿上粗略的分割一些区域,然后这些就是我们要构建的组件,这种拆分是粗粒度的,是凭直觉的。我们一开始不会过多的思考组件的内部实现和子组件划分,但是会考虑 Props 的设计。所以,这是我们为什么说自上而下是一开始相对容易的,符合直觉的,不用过多思考的构建方式。
以一个后台admin页面为例,这个页面是左右布局的,左边是侧边导航栏,右边是对应的内容区域,我们很自然的会把页面拆分为两个大组件,分别是<SideNavigation />
和<Content />
,然后以SideNavigation
为例,考虑到侧边导航栏需要一些列表项,可以得到下面的代码
const navItems = [
{ label: 'Home', to: '/home' },
{ label: 'Dashboards', to: '/dashboards' },
{ label: 'Settings', to: '/settings' },
]
...
<SideNavigation items={navItems} />
总结一下自上而下方式的一些特点:
对于小型项目来说,这个方式没有问题,但是对于多人开发的快速交付的大型项目,在项目迭代的过程中,问题会越来越明显。
产品需求和设计稿发生了变化,我们需要给nav item
加上图标、分割线、需要设置它的类型是link
还是button
,需要知道当前是否是选中的状态等等,所以一些新的属性{ id, to, label, icon, size, type, separator, isSelected }
需要加到navItem
中,然后,在<SideNavigation />
组件内部去新增Props 对应的逻辑。往往这些逻辑通常需要一些 if 分支来渲染不同的UI,渐渐地,这个组件给人的感觉已经不是那么的简单纯粹了。
随着需求的一次次变更,组件的Props 变的越来越复杂,内部的实现逻辑也越来越复杂,当其他人想要复用这个组件时,却发现它有着很复杂的配置,而其中的很多功能可能自己并不需要用到,这个时候会发现这个组件已然变成了一个有着复杂Props 的巨石组件,而且复用性很差。这样的巨石组件通过Props 接收了太多的状态和数据,管理了太多的state
,返回了太多的UI。
巨石组件的一些问题:
相比于自上而下,自下而上不那么直观,最初可能比较慢。因为这种方式会产生很多小组件,而实际中不是每个小组件在最初都需要可复用。所以前期需要花更多时间和努力,让复杂性被封装在每个小组件里。好处是长远看会更快,因为适应性更强。同时避免了单体巨石组件和前面介绍的他会带来的大量问题。
回到上面侧边导航栏的例子,自下而上的构建方式会产生下面的代码结构:
<SideNavigation>
<NavItem to="/home">Home</NavItem>
<NavItem to="/settings">Settings</NavItem>
</SideNavigation>
或者稍微再复杂一下的用法:
<SideNavigation>
<Section>
<NavItem to="/home">Home</NavItem>
<NavItem to="/projects">Projects</NavItem>
<Separator />
<NavItem to="/settings">Settings</NavItem>
<LinkItem to="/foo">Foo</NavItem>
</Section>
<NestedGroup>
<NestedSection title="My projects">
<NavItem to="/project-1">Project 1</NavItem>
<NavItem to="/project-2">Project 2</NavItem>
<NavItem to="/project-3">Project 3</NavItem>
<LinkItem to="/foo.com">See documentation</LinkItem>
</NestedSection>
</NestedGroup>
</SideNavigation>
可以看到,自下而上的构建方式的最终产物还是符合直觉的,它将巨石组件的Props 和复杂内部逻辑拆分到各个相对独立、单一职责的组件内部,最后通过组合
的方式,构成一个大的组件。这样的方式有以下优点:
组合
避免re-render。A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.