使用React和Node.js制作音乐类App的一次总结
一、技术选型
语言选择:
- JavaScript
- TypeScript
- 最终选择了
JavaScript
作为开发语言,一开始尝试使用TypeScript
,但是由于是移动端,antd-mobile的库与TS
有那么一些不兼容,官方文档上也没有像PC端那样推荐你使用TS
,踩过坑,于是换回了JS
。
- 开发环境
create-react-app
目前最好用的开发React
环境 UI组件库的选择:
Swiper.js
个人认为Swiper
在对Vue
的支持会更好,官方文档上也没有明确支持React
antd-mobile
阿里旗下的库,PC
端的功能强大,但是更多使用场景是TO-B
,这里只做尝试使用,个人觉得TO-C
项目不建议使用,本项目中也仅仅使用到了一点点这个组件库的功能- 图标库,
Echarts Bizcharts G2
选择了Bizcharts
,因为它对React
组件化支持更好。
开发所需的包
pubsub-js
对state
的管理的包react-router-dom
路由antd-mobile
官方推荐的按需加载配置less-loader
对less的支持
Node.js端
express
框架(有考虑KOA2框架,但是鉴于express
的成熟性没有选择)puppeteer
爬虫获取数据的包ws
模块,webSocket
的使用request-promise-native
,使用Node.js的服务器无跨域特性发送请求调用网易云音乐接口
- 版本控制工具,毫无疑问使用
Git
- 包管理器,这里使用的是
yarn
,不是npm
TS
和React
。二、项目所需要到的知识点
由于是在移动端,H5 , C3 , 事件处理
还有性能优化考虑的问题要更多基础知识点
- 主打音乐类
APP
,需要使用到的H5
标签,<audio> <video>
等 C3
技术,canvas
,Animation
等制作一些动画- 对移动端的一些特殊情况,比如圆角过圆等的处理。
JSX
语法,比较基本的JSX
语法一定是要非常熟练的ES5/6 TypeScript
,为什么需要TS
的知识? 为了看懂源码,更好调试代码。
- 主打音乐类
React
知识点React
的事件机制,原生事件和合成事件的触发哪个优先级更高,事件代理,事件派发是什么过程?setState
的异步同步问题,其实就是上面的事件机制,这个问题遇到的还是非常多的,如果搞不懂,那么调试起来非常困难React
中追求组件化,个人喜欢组件化到极致,这样方便调试,在使用TS
和React
配合时,调试真的非常简单prop-types
限制传入的props
的类型(隐约有TS
的影子)高阶函数的使用
React中对于大量的重复逻辑函数,使用函数柯里化给予默认参数和封装成高阶函数使用高阶组件
也是用得非常多,对于一些重复逻辑的组件,我们可以封装成高阶组件,即传入值是一个组件,返回的是一个新的组件。React V16
版本的Fiber
架构,跟之前的区别? 新版本的执行render()时候,是分割成多个小任务,可取消中断的过程,配合原生JS
的requestAnimationFrame
(高优先级别的任务处理)和requestIdleCallback
(低优先级别的任务处理),达到性能优化的目的。React
的diff
算法,三种diff
模式:Tree diff
是优先对比两棵树的同级别DOM
节点,所以尽量不要将DOM
节点彻底删除,否则会让React
的render()
时间变长,具体在操作样式时候这点会非常明显,需要将一个元素隐藏时候如果display:none
,如果切换显示和隐藏特别频繁,那么会出现闪屏。Component diff
是对组件的diff
,其实我们可以通过shouldComponentUpdate
的生命周期函数返回值控制组件是否重新渲染,它的两个参数是(nextProps,subState)
,返回值是ture
则重新渲染组件,反之NO
。element diff
,为什么在React
中需要元素要有一个唯一的key
值,因为底层的diff
算法是四根指针,例如遍历两个元素old element: A,C,B,D
;new element B,C,A,D
。 如果没有唯一的key值
,那么diff
算法生成新的虚拟DOM
节点过程是:发现第一个不一样,那么直接插入B,C,A,D
; 但是如果有唯一的key值
,那么React的diff算法
会发现,里面有一样的元素,那么:插入B,C不动,插入A,D不动
。 所以唯一的key
值多重要?
三、移动端的不一样
- 滑动时页面警告
[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. 解决方法 * { -ms-touch-action: pan-y; touch-action: pan-y; }
- 事件点击穿透,禁止一个事件的默认行为,对其手指抬起事件绑定逻辑。
antd-mobile
的按需加载需要配置更多,图标和功能也更少。touches
targettouches
changedtouches
的区别,处理一些复杂逻辑会用到- 在对制作
SPA
单页面应用时,频繁切换的一些元素,做性能优化处理,利用上面提到的那些React
知识点,不然很可能出现闪屏,用户体验感差。 - 在
http
通信时,如果要将返回的数据setState
,那么请注意setState
的同异步场景,准确把控渲染和设置状态时间差逻辑,特别是多个请求,可以使用`promise.all 或者在setState的回调函数中发送请求,定时器把控时间。
promise
对象的值取出,设置成状态重新渲染。`首先在生命周期函数componentDidMount中 this.createSrc() 调用` reqMvList=() => { const {data, src}=this.state; const MvList=data.map(async item => { const result=await reqMv(item.id) const {data: {brs}}=result; return brs[480] }) return MvList } `调用createSrc函数后会先调用reqMvList函数,拿到结果` createSrc=() => { const result=this.reqMvList() let arr=[] result.forEach(item => { item.then(res => { arr=[res, ...arr] return res }) }) `上面将得到的10个promise对象中的值全部取出放到数组中` setTimeout(() => { this.setState({ src:arr }) }, 1000); } `如果此时不加定时器,那么会先执行setState的代码,再去执行promise.then里面的逻辑, 那么其实状态已经更新完了,但是数据是后面添加到arr中的,所以会出现状态里面没有值的情况, 这里需要加一个定时器解决。`
本次构建过程中涉及到的一些面试题
http的ajax轮询 长轮询 keep-alive 和webSocket的区别
如何将一个元素从页面上隐藏 根据场景需求,配合React的Fiber和diff算法机制使用
高阶函数,高阶组件,函数柯里化的使用
如何在一个请求回来数据并且在设置状态成功后发送下面的请求(优雅发送请求,平铺数据)?
手写一个promise
promise.all
的使用pubsub-js
的使用React
的三大属性- 对于高阶组件中的修饰器的使用,例如
@withRouter
cookie和cors
如何配合使用?cookie
可以跨域吗?requestAnimationFrame
和requestIdleCallback
的区别,在React的Fiber中
Node.js端
对request-promise-native
的使用- 现在的性能优化真的只看
DOMContentLoad和Load的时间吗?
可以从RASI
四个方面去看待。
相关推荐
wwzaqw 2020-09-04
游走的豚鼠君 2020-11-10
81417707 2020-10-30
ctg 2020-10-14
小飞侠V 2020-09-25
PncLogon 2020-09-24
jipengx 2020-09-10
颤抖吧腿子 2020-09-04
maple00 2020-09-02
青蓝 2020-08-26
罗忠浩 2020-08-16
liduote 2020-08-13
不知道该写啥QAQ 2020-08-02
pengruiyu 2020-08-01
wmd看海 2020-07-27
孝平 2020-07-18
Eduenth 2020-07-05
iftrueIloveit 2020-07-04