React高级实战 打造大众点评WebApp


前言


本文是个人对慕课网《React技术栈仿大众点评WebApp》的图文总结。

一、项目初始化

(一)初始化项目(npm init)

(二)安装webpack/webpack-dev-server/react/react-dom插件

二、webpack的配置

(一)webpack.config.js

  1. HtmlWebpackPlugin

作用:自动把html与bundle.js挂钩,这样我们就不必手动在index.html下引入bundle.js

  1. OpenBrowserPlugin

作用:启动webpack-dev-server后自动打开浏览器

  1. inline(webpack-dev-server下默认启动)

作用:启动hot reload,即热更新功能。

关闭热更新的方式:

或者在devServer中进行配置:

  1. HotModuleReplacementPlugin(简称HMR)

作用:启动模块热加载,即只更新变更的内容,避免浏览器重新渲染。

首先,什么是Module:

这里需要注意,在devServer里将hot设置为true后,还需要在plugins里通过new的方式启动HMR,否则会报错:

但是如果通过cli命令行的方式启动,即:–hot,则无需如此操作。

(HMR启动成功)。

  1. 配置devserver

注意,根据文档,progress(显示进度)/color(显示颜色)是需要以cli命令行里的形式进行配置:

(二)webpack.production.config.js

  1. plugins插件的配置

(1)BannerPlugin

作用:在打包后的文件内注入banner信息:

效果:

(2)HtmlWebpackPlugin

作用:自动将生成的js等文件与指定的html挂钩,我们就不再需要手动到html里去通过\<script>标签引入bundle.js文件。

(3)OccurrenceOrderPlugin/UglifyJsPlugin

作用:压缩JS模块代码

注意:这两个在webpack4的生产模式下是自动启动的,无需额外配置。

  1. 生产环境下,提取公共模块代码

(1)entry入口分开app和vendor两个入口处理:

其中app代表我们自己写的业务代码;vendor代表依赖包的代码,来源是package.json里的dependencies。

配置好后,在根目录下新建一个空文件夹build,然后执行npm run build命令:

成功打包后,在build文件夹下面可以看到,我们import或者require的依赖包代码都被打包到vendor.js里,业务代码则在app.js里。

(三)关于全局变量process.dev.NODE_DEV的坑

  1. 在package.json的scripts里,通过SET NODE_ENV=development的方式设置node里的process.dev.NODE_DEV全局变量:

  1. 在webpack.config.js里设置全局变量__DEV__来判断当前环境是否为dev:

  1. 然而这里有个坑,测试发现,webpack.config.js里所获取到的process.env.NODE_ENV和在其他js文件下获取到的不一样:

控制台打印出来发现,两个是不对等的:

  1. 实际上,在webpack.config.js里获取到的NODE_DEV为”development “,后面还有个空格,而这个空格产生的原因是我们在package.json的scripts里写下的:

  1. 把空格去掉再试一下:

这下在webpack.config.js里就完全匹配了。

三、react性能优化

(一)react-addons-perf

通过在浏览器控制台,在app跑起来之前Perf.start()锚点,然后运行一段时间后,再Perf.stop(),然后Perf.printWasted()来讲浪费性能的组件打印出来。

四、redux状态管理

(一)安装redux/redux-thunk/react-redux

(二)创建store文件夹,同时创建state.js/reducers.js/actions.js/store.js

–store

—-state.js // 用于存放state的初始状态

—-reducers.js // 通过switch对不同的输入return不同的输出(纯函数,本身并不改变任何state)

—-actions.js // 定义不同的操作(每个操作返回一个)

—-store.js // 创建store(一般会在此引入中间件)

  1. state.js

  1. reducers.js

(1)引入combineReducers来处理多个reducer的情况

  1. actions.js

  1. store.js

(1)thunk是redux里一个中间件,用于处理异步dispatch

(注:因store.dispatch本来只能接受action对象作为参数)

(三)在根目录入口文件里引入store

注:Provider的作用是将store作为全局props,这样后面所有的组件都能获取。

(四)在需要用到store的组件里引入react-redux

同时,把actions也引入。

这里mapStateToProps和mapDispatchToProps的作用分别是把state和dispatch映射到props里。

这样,就能在componentDidMount里通过this.props获取到dispatch。

同时也能在render里获取state了。

(五)在需要dispatch的地方执行action即可触发redux

这里总结起来一幅图:

(六)Redux DevTools的使用

  1. 在谷歌商店里下载redux-devtools

安装成功后,在chrome开发者模式下可以看到Redux的选项。

  1. 更新store.js里的相关配置,引入compose来合并thunk中间件

  1. 查看效果

五、fetch基础

(一)安装whatwg-fetch和es6-promise依赖

(二)app目录下创建fetch文件夹

创建test.js

(三)封装get和post请求

六、数据mock

这部分使用node里的后端框架koa来实现。

(一)安装koa

(二)在根目录下创建mock文件夹,里面新建server.js

  1. 配置server.js

注:根据koa2的文档,koa引入后需要通过new构造的方式创建。

  1. 在webpack.config.js的devServer里配置端口代理

备注:这是因为我们在上面app.listen()里监听的是3000端口,而我们的项目是在8080端口运行的,如果从8080端口往3000端口发送http请求的话会遇到跨域的问题,所以这里通过devServer里proxy代理的方式解决。

  1. 在package.json里的script脚本里增加mock命令

  1. 执行npm run mock

看到这样即代表mock的server已经跑起来了。

  1. 到组件里试试发送get和post请求

七、首页制作

(一)首部header组件

(二)轮播图

  1. 创建轮播组件Category.jsx

  2. 根据react-swipe文档,安装相关依赖包

  1. 根据文档编写ReactSwipe内容

  1. 编写轮播参数

  1. 通过this.state.index来控制轮播序号的变化

  1. 效果

(三)超值特惠

(四)推荐列表(猜你喜欢)

  1. 如何在koa2里获取router里的url中传递的参数?

方法如下:

注意,这里的console打印出来并不是在浏览器内部,而是在命令窗里:

  1. react中如何获取dom元素?可以用refs:

  1. 实现滚动到底部自动加载数据的功能

原理是在HomeLoadMore组件里,通过监听scroll事件设定定时器,利用getBoundingClientRect的api实现。

八、城市页制作

城市页编写中,由于需要获取及修改城市信息,所以需要用到redux及localStore。

  1. 使用bindActionCreators将setCity与dispatch绑定起来,然后通过mapDispatchToProps及connect组件传递到props里:

  1. 在changeFn里去执行通过props获取的setCity这个dispatch,改变redux中的cityInfo这个state,然后再同步改变本地缓存:

  1. 查看效果

  1. 功能补充:在更改城市后,应当跳转到首页

注意:在react-router-dom里,是通过this.props.history.push()来实现。

九、搜索页制作

(一)更新轮播组件Category,加入Link组件

(二)更新routerMap.jsx里的路由设置

上面更新好轮播组件的Link组件后,在首页点击轮播小图会进入到search路由,但是发现结果被分配到404页面了:

这是因为我们在routerMap.jsx里的路由设置的问题:

这里我们需要为search配置可选路由参数:

在react-router旧版本里,是通过括号来实现的:

但是这在react-router v4后不行了,要改为

(三)完成搜索栏功能

这里我们先把之前在HomeHeader里的input改为HomeSearchInput组件,然后通过onKeyUp监听用户输入内容:

注意,这里的重点是,在当用户按下回车(即keyCode为13时),我们要跳转到搜索页,而在HomeSearchInput组件里是无法获取this.props.history的(react-router-dom里,只有在router的component关联的组件里才能获取props.history),所以我们需要额外安装一个history依赖包:

然后,通过createHashHistory函数,来实现路由跳转。

(四)查看效果

十、详情页制作

(一)完成效果

(二)编写过程和前面类似,不赘述,有几个值得注意的:

  1. react中插入html元素的方式

通过dangerouslySetInnerHTML的接口来实现。

  1. 星级的实现方式:

十一、登录页

(一)完成效果

(二)需要注意的几点:

  1. redux中state为对象的更新方式

十二、购买和收藏功能

(一)完成效果:

(二)值得注意的地方:

十三、用户中心

(一)完成效果

(二)这部分制作和前面的类似,并无什么需要注意的。

十四、评价(用户中心)

完成后的效果:

0%