项目介绍
阿里交叉面的面试官介绍了技术框架React+Redux+AntD,使用新技术把自己的iOS极简事项改写为前端版本。
项目优化
其实项目本身比较简单,我自己就从优化的方面去进行了思考。
1 React本身的性能优化方法:
- 使用虚拟DOM。减少生成真实DOM时间,且DOM对象比对加快。
- 虚拟DOM的比对。同层比对+使用key值比对,提升虚拟DOM比对速度
- react16,setState性能提升机制,使用异步函数:多次数据改变结合成一次来做,降低虚拟DOM频率
2 性能优化:
渲染优化:
- 1 作用域修改放在constructor构造函数内,保证作用域绑定操作只执行一次 + 避免子组件的无谓渲染。
1 | this.handleClick = this.handleClick.bind(this); |
- 2 借助生命周期函数:shouldComponentUpdate,提高react组件性能,避免无谓的组件render渲染。
异步优化:
3 发送ajax请求,放在componentDidMount
- 原因:ajax只需要请求1次,需要在渲染前获取数据。场景:使用ajax异步请求的方式,从我的一个接口上,请求一个远程的todolist数据,将远程数据加载到本地,渲染到页面上。
4 Redux-thunk中间件实现ajax数据请求。
把异步操作的代码从组件中移除,移除到action中去。使用redux-thunk后,action不仅可以是一个action对象(JS对象)了,还可以是一个函数。
原因:
把异步函数放在生命周期函数中去做,该生命周期函数会越来越复杂且多,组件会越来越大。
好处1:应该把复杂的业务逻辑和异步函数拆分到一个地方去管理。借助redux-thunk,放在actionCreator去管理。
好处2:放在actionCreator的时候,自动化测试时,测试getTodoList方法,比测试生命周期函数要简单的多。
异步组件react-loadable:一个动态导入加载组件的高阶组件。页面异步,分割成多个js文件。按需加载 (懒加载)
- loadable.js:loader:本页面。loading:加载时候显示的内容。
- App.js,from修改loadable.js,使用withRouter,让detail有能力获取Rounter的所有参数和内容,即可以获取id。
3 维护性优化,方便测试和找BUG:
- React是函数式编程,使用前端自动化测试:只需要给函数一个数值,查看输出是否符合预期。
- propTypes:组件要接受外部传过来的值,进行类型校验。验证传值。DefaultProps:若父组件未向子组件传值,定义属性默认值。设置默认值
- ActionTypes的拆分:action判断的时候,若常量写错了会报异常,字符串不会报异常。方便找出bug。
- 使用actionCreators统一创建action:自动化测试,有利于代码维护,不然每一个绑定事件的函数都要写一个生成的action,不利于大型项目的维护。
- 使用UI组件和容器组件,分离UI操作和逻辑操作。
- 无状态组件:当普通组件只有render函数的时候,可以使用无状态组件替换该组件。
- 普通组件的性能比不上无状态组件的性能高 。无状态组件就是一个函数;普通组件是JS的类,类生成的对象里面还有生命周期函数,执行的时候既要执行函数,又要执行render。
- React-Redux重写TodoList:
- Provider组件:核心组件,把store提供给每一个内部组件,也叫提供器
- 连接: connect方法,前两个参数为连接的规则,最后的参数为本组件TodoList。
- 结果=》todoList是一个UI组件,connect把UI组件和业务逻辑(数据、派发)结合,返回的结果为一个容器组件。
项目对比
目标相同:展现UI,监听用户。js单线程。ios主队列=刷新页面。
UI设计:
- storyboard和纯代码(snp布局)实现
- react组件化来实现
传值:
- 前端是属性传值、子组件调用父组件方法传值。
- iOS使用segue正向传值,自定义protocal-delegate反向传值
耗时操作:HTTP等放在异步操作。
✨需要优化性能:
知识点
Redux:数据层框架。将组件中的数据放在一个公用存储区域去存储,组件改变数据,其他组件会感知Redux的改变,再去取数据更新组件。
AntD:统一中台项目的前端 UI 设计,减少设计成本(大型前端项目可能不适用,适合管理系统)
React:构建用户界面的JS库。用于构建UI, 是 MVC 中的 V(视图)。
需求分析
功能:
1 新增任务功能:输入inputValue+添加Item ;2 删除任务功能:
组件:
1父组件:新增任务、浏览任务; 2子组件:单个任务的item。
步骤
初始实现:
一开始是没有使用Redux来存储数据,主要用于父子组件传值来实现功能。
父组件向子组件传值:父组件的属性
父组件通过属性的方式向子组件传递参数
子组件通过props的形式接收父组件传递的参数
子组件向父组件传值:通过调用父组件的方法改变数据
父组件将方法传递给子组件,子组件调用该方法,需要传的值作为输入参数
Redux实现功能:
1 Store的创建
- 1 创建reducer,把reducer传递给创建store的函数:
- 输入为state和action,返回为NewState
- 有一个default值
- 2 创建store,使用reducer作为参数
2 组件发送需要改变state的action
1 方法内现写action要做什么的那句话(对象)
2 将action传递给store
1
store.dispatch(action);
3 store不操作,将action传递给reducer
4 在reducer中,判断action+操作
- reducer中判断type
- 深拷贝原来的state为newState,更新newState
- 返回newState给store
5 store接受后会替换之前的state
3 组件监听state的改变
1 | // 1. 组件去订阅store.subscribe |