使用hooks重构antd pro的想象力(二)

简介: 深度学习的前景甚至远超当年的iOS,这是一股更大的风。从资本投资的角度来看,目前所有的投资方向基本上来说都已经饱和,很难出现新的机会。所有资本家都在关注人工智能。也就意味着,人工智能的新项目,已经处于爆发式增长的档口,未来相关的人才缺口将会远超想象。而世界上大多数做深度学习研究的团队,都是使用的python语言。python有多火?一件小事就可以表明。前不久,地产大佬潘石屹,突然发微博说,“今天我开始学习一门新的语言Python”

中午吃饭的时候在跟同事讨论当年iOS的刚出江湖时的盛况。大家都在感慨当年为什么没有选择选择成为一名iOS程序员,否则早就财务自由买车买房了。


大三的时候iOS名声不显,可神奇的是我们居然开设了一门必修课Object-C,老师胖胖的爱吹牛,说学了我这门课,毕业随便找个8000以上的工作没有问题。


2012年的月薪8000,就是现在的月薪2万以上。还是在成都。


全班40多个人一群蠢蛋,只有一个人相信他。那个人当年实习工资6000+。我们才发现,那老师不是在吹牛,而是在谦虚!


所以我们几个围在一起在感叹,在风口的时候能抓住机遇,真的非常重要。


而IT行业未来几年的风口是什么?


一定是Deep Learning 深度学习!,通俗点来说,就是人工智能。


深度学习的前景甚至远超当年的iOS,这是一股更大的风。从资本投资的角度来看,目前所有的投资方向基本上来说都已经饱和,很难出现新的机会。所有资本家都在关注人工智能。也就意味着,人工智能的新项目,已经处于爆发式增长的档口,未来相关的人才缺口将会远超想象。


而世界上大多数做深度学习研究的团队,都是使用的python语言


python有多火?


一件小事就可以表明。前不久,地产大佬潘石屹,突然发微博说,“今天我开始学习一门新的语言Python”


微信图片_20220510230045.jpg


而对于程序员来说,python已经和Js一样,成为我们必备的技能之一。专业的Python程序员,在北京平均月薪都能达到2万。


微信图片_20220510230135.jpg


好在Python也足够简单,通过一系列课程学习,基本上很快就能上手。


想要学Python的同学,给大家推荐一套免费课程。这套课程从基础知识点作为起点,帮助大家搭建一个完整的Python知识体系。并且准备了一整套编程实战演练课程。是入门Python的一个非常好的选择。




好了,说回正题。这篇文章的主要目的还是继续利用React hooks的思维重构antd pro。

而今天的关键,就是要进一步深入掌握组件化思维。

组件化思维所有人都在提,听上去似乎很简单,可是真正能够运用好的,却并不多。这里以antd pro的官方demo项目中的分析页为例,跟大家一步一步分享一下如何划分组件。

1


先看看页面。

微信图片_20220510230214.jpg

从页面布局效果来看,这个页面的组件非常好划分,因为已经都用框框把每个单独的组件划分好了。


第一步,我们的组件可以划分如下:


// 总销售额
<TotalSales />
//  访问量
<VisitorCount />
// 支付笔数
<PayAmount />
// 运营活动效果
<ActivityEffect />
// 销售额访问量的图表
<SalesCard />
// 线上热门搜索
<TopSearch />
// 销售额类别占比
<ProportionSales />
// 离线数据图表
<OfflineData />


第二步我们发现,有几个模块长得差不多。

image.gif

因此,这里可以使用同一个容器组件来处理这种有类似样式的模块。如果将这四个模块放在同一父组件IntroduceRow来处理,这个页面最顶层的父组件,也就是我通常说的页面组件就应该由如下几个组件合并而成。


// 四个长相类似的块合并成一个组件处理
<IntroduceRow />
// 销售额访问量的图表
<SalesCard />
// 线上热门搜索
<TopSearch />
// 销售额类别占比
<ProportionSales />
// 离线数据图表
<OfflineData />


第三步我们要思考的一个问题是,当这些组件在页面组件中使用时,需要往他们里面传入什么参数?


在确认传入参数时,我们需要思考几个重要的问题


当前组件是否跟别的组件共享数据?


如果共享数据,这个数据应该在哪里处理比较合适?


从页面中分析可以得出,只有一个组件的操作会影响到其他页面。


如图,SalesCard组件选择日期时,需要接口重新请求数据。这也是因为接口设计不合理导致,因为整个页面那么多数据只有一个接口。合理的设计是这个组件的数据应该由一个接口提供。


微信图片_20220510230221.jpg


因此,如果基于props传参的思路,页面组件大概会是这个样子


// 四个长相类似的块合并成一个组件处理
<IntroduceRow visitData={visitData} />
// 销售额访问量的图表
<SalesCard salesData={salesData} selectDate={selectDate} />
// 线上热门搜索
<TopSearch searchData={searchData} />
// 销售额类别占比
<ProportionSales salesPieData={salesPieData} />
// 离线数据图表
<OfflineData offlineData={offlineData} />


官方demo中,并未思考这么多,而是将仅属于子组件的操作放在父组件处理,让父组件变得复杂,因此不合理。


微信图片_20220510230225.png


这样分析之后,就将所有的组件隔离开,子组件内部的事情,就可以各自单独思考了。


2


组件化的第二个非常重要的思考,就是对于能够影响组件显示内容的数据如何处理。


经过前面的学习(useContext章节)我们知道,当不同的子组件共享了数据,那么就让该数据在他们共同的父组件中来维护。否则,就单独在子组件中自己维护。


由于整个页面中,所有的数据都是来自一个接口,因此,所有的组件共享一个数据来源,也就意味着,该数据成为了共享数据,应该在父级中维护。


在这里我们要站在更高一个层级来思考这份数据的处理。官方demo中,将页面数据维护在全局Store中。是否合理呢?


显然不合理。


从整个全局App的角度考虑,当前页面组件也是一个子组件。而该页面组件的内容,和其他页面相比,其实是独立的。


如果我们希望页面切换时,缓存当前页面的数据,当切换回来不需要重新请求接口,那么放在全局Store来维护是合理的,但是操作几个页面之后发现,官方Demo中的意图是希望当切换回来时,页面重新加载。


所以,当前页面独立的数据,不应该放在更顶层的父组件中去管理,而仅仅只在当前页面就可以了。


3


loading的处理


从整个页面来看,因为是一个接口请求过来了所有数据,因此对应的,也只能有一个loading来处理整个页面的加载状态。而不是将loading状态传入子组件中处理。

那么使用中间件dva-loading来统一处理全局的loading是否是好的解决方案呢?

当然不是。


dva-loading让整个项目全局共享一个loadingEffect对象


export interface LoadingEffect {
  effects: {
    [key: string]: boolean
  },
  global: boolean,
  models: {
    [key: string]: boolean
  }
}


也就是说,无论你的组件如何划分,loading都不可避免的成为了共享状态。可是在很多情况下,我们仅仅只希望loading成为当前页面或者某个子组件的私有状态。因此dva-loading虽然看上去简化了写法,却让组件化思维固化,失去了灵活性。


也正因为处于最顶层的共享数据,当loadingEffect状态改变时,会导致额外的冗余渲染。因此,dva-loading应该慎用。


4


分析到这里,分析页的重构方案就已经比较明确了。父组件维护共享数据,子组件维护仅属于自己的数据。


页面组件伪代码大概如下:


export function Analysis() {
  const [dashboardAnalysis, setDashboardAnalysis] = useState<AnalysisData>();
  const [loading, setLoading] = useState(true);
  const {visitData, salesData, searchData, salesPieData, offlineData} = dashboardAnalysis;
  useEffect(() => {
    if (!loading) {
      return;
    }
    api().then(res => {
      setDashboardAnalysis(res.data);
    })
  }, [loading]);
  return (
    <GridContent>
      // 四个长相类似的块合并成一个组件处理
      <IntroduceRow visitData={visitData} />
      // 销售额访问量的图表
      <SalesCard salesData={salesData} selectDate={() => setLoading(true)} />
      // 线上热门搜索
      <TopSearch searchData={searchData} />
      // 销售额类别占比
      <ProportionSales salesPieData={salesPieData} />
      // 离线数据图表
      <OfflineData offlineData={offlineData} />
    </GridContent>
  );
}


日期选择时,设置loading为true,触发useEffect重新请求接口。这样处理是因为没考虑接口参数,如果考虑参数,则方式会不一样。


很显然,和官方Demo原有的方案相比,页面组件简单了许多,从最终结果看,这个复杂的页面,其实就和我们最简单的计数案例差不多。


合理的组件化思维运用,会省去非常多的额外概念,你看,优化到最后,甚至我们连redux的影子都看不到了。


这就是大道至简的真谛!

相关文章
|
7月前
|
JavaScript 前端开发
Ant Design Vue 从V3到V4的升级原来进行了这个技术的调整
Ant Design Vue 从V3到V4的升级原来进行了这个技术的调整,你有了解吗?
488 0
|
存储 前端开发 JavaScript
ahooks 正式发布:值得拥抱的 React Hooks 工具库
ahook定位于一套基于 React Hooks 的工具库,核心围绕 React Hooks 的逻辑封装能力,降低代码复杂度和避免团队的重复建设为背景,共同建设和维护阿里经济体层面的 React Hooks 库。
22811 1
ahooks 正式发布:值得拥抱的 React Hooks 工具库
|
4月前
|
JavaScript 前端开发 开发者
【颠覆你的前端世界!】VSCode + ESLint + Prettier:一键拯救Vue代码于水深火热之中,打造极致编程体验之旅!
【8月更文挑战第9天】随着前端技术的发展,保持代码规范一致至关重要。本文介绍如何在VSCode中利用ESLint和Prettier检查并格式化Vue.js代码。ESLint检测代码错误,Prettier保证风格统一。首先需安装VSCode插件及Node.js包,然后配置ESLint和Prettier选项。在VSCode设置中启用保存时自动修复与格式化功能。配置完成后,VSCode将自动应用规则,提升编码效率和代码质量。
552 1
|
4月前
|
前端开发 JavaScript 测试技术
React Hooks vs. Class Components的奥秘:如何用新时代开发模式让你的项目一鸣惊人?
【8月更文挑战第31天】在现代Web开发中,React提供了两种主要的组件实现方式:Hooks和Class Components。React Hooks自16.8版本推出,允许开发者在不使用类的情况下访问状态和生命周期方法,提高了函数组件的功能性和开发效率。Class Components则基于JavaScript类,提供了丰富的生命周期方法,便于精细控制组件行为。尽管两者在代码组织、性能及开发效率上各有千秋,但随着Hooks的普及,前端开发模式正逐渐转变,Hooks因其实现简便性成为越来越多开发者的选择,而在需要细致管理生命周期的场景下,Class Components仍具优势。
52 0
|
6月前
|
缓存 前端开发 JavaScript
React Hooks 一步到位
React Hooks 一步到位
|
7月前
|
前端开发
【边做边学】系统解读一下React Hooks
【边做边学】系统解读一下React Hooks
|
前端开发
【React工作记录一百零一】再次接触老朋友react+ant design table合并单元格(2)
#yyds干货盘点 再次接触老朋友react+ant design table合并单元格
102 0
|
JavaScript 前端开发 算法
迷你版Vue--学习如何造一个Vue轮子
迷你版Vue--学习如何造一个Vue轮子
55 0
|
前端开发 数据格式
【React工作记录一百零一】再次接触老朋友react+ant design table合并单元格(1)
#yyds干货盘点 再次接触老朋友react+ant design table合并单元格
110 0
|
JavaScript 前端开发 API
Vue2 彻底从 Flow 重构为 TypeScript,焕然一新!
事情起源于 4 月 7 号晚上,尤雨溪在推特说,Vue2 收到了一个将整个代码库迁移到 TypeScript 的 PR。