My Little World

表单 & 列表

表单功能点

  1. 初始数据,提交和跳转

表单各项配置的优化,可以通过对UI框架的API进行封装成高阶组件,然后在使用时,通过配置高阶组件的属性,将需要的配置项传递给UI框架API,减少代码冗余,配置清晰

提交后状态通过中间件返回promise判断接下来操作

2.
错误处理(可依靠UI框架进行判断)
动态表单元素(在传入高阶组件属性时采用函数返回值形式动态加载表单元素,在函数中处理要不要显示表单元素)
内容动态加载(在componentDidMount中进行数据请求,以及初始状态处理)

列表页功能点

搜索,数据缓存和分页

开发列表也要考虑的技术要点
1.如何翻页 (数据来自服务器还是客户端缓存)
2.如何进行内容搜索 (当前页面数据搜索还是服务器端数据搜索)
3.如何缓存数据
4.何时进行页面刷新

列表页数据通过store拿数据渲染,翻页,查找,刷新通过触发action然后从服务器拿到数据后,更新store,从而组件重新渲染

store 模型
listItems:当前页id集合数组[id1,id2]
byId:{id1:{id:id1,name:xxx},id2:{id:id2,name:xxx}}
keyword:关键字string
page:number 页数
fetchListPending:bool是否正在加载数据
FetchListError:OBJECT数据加载出错
listNeedReload:bool是否需要重新加载(做判断条件,例如编辑之后,设为true,在列表页拿到判断为true则重新获取列表数据)

URL设计
将页数和关键字当做路由参数传递在componentDidupdated中获取参数判断是否重新获取数据

缓存更新,加载状态,错误处理

通过store模型中的相关数据进行判断展示

页面数据需要来源多个请求的处理

页面数据来自多个请求
1.请求之间无依赖关系,可以并发进行
2.请求有依赖,需要依次进行 (promise)
3.请求完成之前,页面显示 Loading 状态
loading数据状态由当前数据推导确定

内容页的加载和缓存

内容页和列表页的数据关系
1.简单业务:列表页数据包含内容页的数据 (注意页面刷新情况数据的获取)
2.复杂业务:内容页数据需要额外获取 (每次进来都重新获取)
3.内容页数据的缓存(将数据放在store中,在store中拿数据)

基于React Router 实现分步操作

向导页面需要考虑的技术要点
1.使用 URL进行导航的好处 (可以直接刷新其中一个步骤)

  1. 表单内容存放的位置
  2. 页面状态如何切换

将表单元素放在一个统一的form中,通过路由判断第几步,进而显示不同的表单元素,需要注意的是,切换下一步时,当前组件消失,配置的数据也会消失,需要将当前所填数据进行保存,以便在返回上一步时有数据

集成第三方 JS 库的技术要点

1.使用 ref 获取原生 DOM 节点引用
2.手动将组件状态更新到 DOM 节点
(对于数据驱动UI展示的情况,第一次渲染和之后更新需要手动操作DOM的过程,将数据注入过程隔离出来,单独处理成一个函数,再当react 部分操作导致需要重新渲染时,再调用,将react状态映射到第三方DOM中)
3.组件销毁时移除原生节点 DOM 事件

基于路由实现菜单导航

1.菜单导航只是改变 URL 状态
2.根据当前 URL 显示菜单的当前状态(使用navLink标签实现,注意react-router和redux一起使用时,url发生变化,组建要重新render时,必须要让组件绑定到router的store上,即让react-router也一起渲染)

如何避免应用出现性能问题

1.了解常见的性能问题场景 (键盘输入,鼠标移动是否卡顿)
2.时刻注意代码的潜在性能问题 (何时拆分组件,有优化空间;能否高效更新,组件拆分是否够细,足够细的话,组件越接近纯函数,就越可能减少参与到diff操作的可能性,从而提高渲染速度)
3.注重可重构的代码 (代码耦合性低,几乎不依赖外界,也不被外界依赖,对于有重构可能性的代码保留重构空间,当其他优先级较高的性能问题解决后,再进行代码重构)
4.了解如何使用工具定位性能问题

网络性能优化:自动化按需加载

1.什么是按需加载 (切换页面时才加载相应页面,而不是一开始就将所有页面加载进来)
2.使用 Webpack 的 import API
3.使用 react-loadable 库实现 React 异步加载
利用分包加载,在配置路由时实现,在总路由中删除,防止打包到总包中

1
2
3
4
5
import loadable from 'react-loadable'
const listPage = loadable({
loader:()=>import ('./listPage'),
loading:()=><div>loading...</div>
})

listPage页面在加载该页时,会自动加载listPage的独立打包文件

使用 reselect 避免重复计算
reselect 可以创建自动缓存的数据处理流程,通过保存计算结果,避免重复计算

异步渲染的两个部分

时间分片
DOM操作的优先级低于浏览器原生行为,例如键盘和鼠标输入,从而保证操作的流畅。
(setstate导致的重新render等页面行为(滚动,输入)结束后再执行)
1.虚拟 DOM 的 diff 操作可以分片进行 (对操作进行序列化,然后进行合并或者优先级处理)
2.React 新 API: unstatble_deferredUpdates(低级别的setstate)
3.Chrome 新 API:requestIdleCallback(浏览器级别的api,告诉代码内存空闲(不再滚动或敲击键盘),可以进行一些之前优先级低的UI更新操作,时间分片基础)

渲染挂起
虚拟DOM节点可以等待某个异步操作的完成,并指定timeout后,才完成真正的渲染
(可以不再注意什么时候显示loading状态,取消loading状态,虚拟dom节点可以自己等待异步操作的完成,只要虚拟dom节点返回一个promise,渲染引擎就会等promise结束后再去render)

  1. 新内置组件:Timeout

  2. unstatble_deferUpdate

借助工具发现性能问题

1.使用 React DevTool 找到多余渲染
chrome 插件,可查看react应用的状态,帮助找到不必要的render,从而进行调优—> [highlight update]
2.使用 Chrome DevTool 定位性能瓶颈
什么样的组件花了多长时间做了什么样的渲染—>performance