React全家桶实战-react版的cnode webapp

1,983 阅读7分钟

前言

学习一门前端框架,不动手是不行的。所以当我学习react有一段时间时,就打算开始写一个react的个人项目,前后端一起写的话,比较耗时间,所以就选了提供了优质api的Cnode社区,感谢。(如果我参与的合作项目,产品选的技术栈是react的话,我也不用自己写个app了,Orz)

希望各位大爷给个star勒,就右上角轻轻一点,比心

传送门:源码地址

最近用mobx重构了一遍,也发了篇文章,传送门

Demo

demo
demo

过程

分析需求

需求是做一个社区的webapp,首先一个社区的功能,就有 登录注册(这次没有注册)自己的信息发帖查看别人的发帖查看别人的主页评论他人的帖子等等等。功能太多,我们开发时总不能这部分做点,那部分做点。我们得将这些功能变成一个一个可拆解的模块,比如下图便是我的分块,

需求分析
需求分析

现在分块出了个雏形,那么就有的放矢了。我们开发时,可以先从某一个块开始动手。比如可以先从登录这一块开始,每个独立的模块开发完成后,可以进行连接,其实主要是路由的转跳。完成后,可以进行调试,看看整个跑起来感觉如何(我只在我的安卓机调试了一遍)。

选型

其实做webapp, 我更喜欢用Vue, 但是一开始我的目的就是打算用react的技术栈进行一次实战。react,redux, react-redux这三样是跑不掉的,虽然我一开始是想用dva,但是我看了一遍,觉得还是用前者好了,原因不是dva不好,个人项目还是看我个人的学习目的而选择的。不过从dva中看到的一个redux处理异步action的中间件,redux-saga。虽然redux-thunk加上async await可以基本满足业务开发的需求。但是我感觉redux-saga更优雅一点。主要是它让我们发起一个异步action时,能像发起同步action一样,其次就是它的监视和执行的机制吸引了我,本着学习的目的,选用redux-saga处理异步action(当前它很适合用来测试)。UI框架为了迅速开发就选用了antd-mobile。发起http请求就用了axios。脚手架就用了create-react-app

编码

这里主要说下编码时遇到的问题和解决的方法:

  • 首先是路由的懒加载。react-router这个项目用了3.x的。然后,由于是web app而且是一个单页面应用。当项目变大时,打包后的js太臃肿。用户第一次进到这个页面,要下载太大的js导致首屏加载太慢。所以路由的分块是很必要的。但是,重点来了。react-router官方的文档,动态路由是webpack1的require.ensure,这个不是什么很大的事,主要那个写法也不太一样了。下面旧新对比:

旧

新

折腾一个小时,总算搜到正确的写法,并达到了分块的效果。

  • 其次antd-mobile的listview。这个组件用于展示列表。其中有一个属性是 useBodyScroll, 意思就是以body作为滚动的容器。这个项目有一个需求,就是在详情页时,评论就是一个长列表。那么我自然是想让它以body作为滚动容器,但是,一直触发不了到达底部的事件,除了一开始可以触发一次。百思不得其解,干脆,就自己监听body的滚动事件,判断到达底部,然后调用loadMore的事件,加载评论。

  • 注意组件的更新顺序。父组件render时,会等子组件渲染完了,才会DidMount,所以如果子组件和父组件都为一个dom绑定了一个事件的话,最后父组件的绑定会覆盖子组件的。

  • 然后还是路由。举个例子: /user/1 => /user/2,这类转跳,是不会触发组件的生命周期的,我在vue也遇到过。暂时没去看源码,首先我想到的解决方法就是当这类转跳发生时,比较两个路由,如果除了参数那部分都一样的话,就提取新路由的参数,更新数据,重新渲染。如果你有更好的方法,告诉我谢谢!

  • 还有一个就是引入模块的。假设一个模块里有好几个函数或组件,但是我们只要用其中一个,我们这样导入时
    import { x } from y;
    webpack可是会帮你把这整个模块都打包进来的,如果这个模块有1000个函数或1000个组件,那么为了引入一个,打包其余的999个。。可想而知问题多大了。

  • 最后就是减少重复代码吧。比如我的收藏,最近回复,最近话题等的样式和逻辑都很类似。那么没必要都写一遍啊。封装一个组件,然后根据需要传props进入就可以达到复用的目的。长列表组件也是。没必要为每个长列表都写一遍。你只要抽取其中的逻辑,封装起来,通过传入props来个性配置使用就好。

大概就上面这么多。其余一些由于断断续续开发,没有及时记录下来,所以忘了。改天回忆一下。

测试

测试就暂时没做,手动测试了一遍。

反思

  • 一个产品的开发流程,到我这就剩上面的几部分。开发这个web app时,对于 redux掌管数据,react只要负责视图渲染的说法有了一些新看法。对于庞大的项目来说,这样分开,应该很方便维护。react的组件尽量是无状态的组件的话,我们只要管好数据,它就会正常地工作,这也是纯函数的优点,关注点比较专一。也方便合作,比如一个前端工程师负责页面UI,一个负责数据。这样合作起来,找bug也很方便。但是开发小型应用时,这样有点大材小用,就把方便的事情硬是搞复杂了。所以,使用redux的话,不用用到react就下意识决定用redux吧。综合考虑,如果项目不小,而且未来会越做越大,解耦是最好的,数据和UI分开,后期方面增加新的东西,又不会显得臃肿,一团麻花。如果做些小项目练手或者未来不会计划开发下去的,直接在组件的state来保存数据也可以。

  • 关于轮子。工程开发如果用成熟的轮子能完美解决是最好的。那就尽量别自己写轮子。毕竟人家的star就证明是千锤百炼的了。但是有时候,实在解决不了,可以选择看源码,找问题。也可以造轮子,达成业务需求。也建议我,你们平时多看源码, 理解实现原理对于开发也是很有帮助的。

  • 关于写代码,写代码前先想好再写吧。真的,不然发现实现不对或者和需求不符合,你又得再来过。比如,路由分块,一开始觉得怎么简单怎么来,没意识到页面越来越多,分块的需求越来越重要,那么你又得重新写router哇。而且那一大堆路由,有得你写的了。如果平时加一个页面就写好了,那就不用付出这多一分劳累了。再比如,我开发点赞评论的saga时,脑子一热,觉得点赞和取消不就是一个流程么,点赞后,才能触发取消点赞的action。这里就没有考虑到,一个用户同时需要多好几个人点赞,但是这个时候并不需要取消点赞。那么按一开始的方法写,点赞后,只能接受到取消点赞的action,并执行完这个异步http, 才能再接受到点赞的action。那么用户除了第一个点赞的评论正确执行外,其余的都会被忽略到。那就发生了错误。所以写的时候就得仔细想好逻辑。