webpack公共配置
|
从零搭建React全家桶框架教程
最新推荐文章于 2024-11-08 11:21:24 发布
本文详细介绍了一个完整的React项目从搭建到优化的全过程,包括React、Redux、React-Router等技术栈的使用方法及最佳实践。
本文详细介绍了一个完整的React项目从搭建到优化的全过程,包括React、Redux、React-Router等技术栈的使用方法及最佳实践。
webpack公共配置
|
1036
1万+
9570
当我第一次跟着项目做
react项目的时候,由于半截加入的,对框架了解甚少,只能跟着别人的样板写。对整个框架没有一点了解。做项目,总是要解决各种问题的,所以每个地方都需要去了解,但是对整个框架没有一个整体的了解,实在是不行。
期间,我也跟着别人的搭建框架的教程一步一步的走,但是经常因为自己太菜,走不下去。在经过各种蹂躏之后,对整个框架也有一个大概的了解,
我就想把他写下来,让后来的菜鸟能跟着我的教程对
react全家桶有一个全面的认识。我的这个教程,从新建根文件夹开始,到成型的框架,每个文件为什么要建立?建立了干什么?每个依赖都是干什么的?一步一步写下来,供大家学习。
当然,这个框架我以后会一直维护的,也希望大家能一起来完善这个框架,如果您有任何建议,欢迎在这里留言,欢迎
fork源码react-family。我基于该框架
react-family又做了一个兼容IE8的版本,教程在这里react-family框架兼容IE8教程。cd src/pages mkdir Home创建文件夹并进入
mkdir react-family && cd react-familyinit npm
npm init按照提示填写项目基本信息安装
webpacknpm install --save-dev webpackQ: 什么时候用
--save-dev,什么时候用--save?A:
--save-dev是你开发时候依赖的东西,--save是你发布之后还依赖的东西。看这里根据webpack文档编写最基础的配置文件
新建
webpack开发配置文件touch webpack.dev.config.jswebpack.dev.config.js学会使用
webpack编译文件新建入口文件
mkdir src && touch ./src/index.jssrc/index.js添加内容document.getElementById('app').innerHTML = "Webpack works"现在我们执行命令
webpack --config webpack.dev.config.js我们可以看到生成了
dist文件夹和bundle.js。现在我们测试下~
dist文件夹下面新建一个index.htmltouch ./dist/index.htmldist/index.html填写内容用浏览器打开
index.html,可以看到Webpack works!现在回头看下,我们做了什么或者说
webpack做了什么。把入口文件
index.js经过处理之后,生成bundle.js。就这么简单。通俗的说,就是我们可以用ES6, ES7等来编写代码,Babel会把他们统统转为ES5。
npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-0新建
babel配置文件.babelrctouch .babelrc.babelrc{ "presets": [ "es2015", "react", "stage-0" ], "plugins": [] }修改
webpack.dev.config.js,增加babel-loader!/*src文件夹下面的以.js结尾的文件,要使用babel解析*/ /*cacheDirectory是用来缓存编译结果,下次编译加速*/ module: { rules: [{ test: /\.js$/, use: ['babel-loader?cacheDirectory=true'], include: path.join(__dirname, 'src') }] }现在我们简单测试下,是否能正确转义ES6~
修改
src/index.js执行打包命令
webpack --config webpack.dev.config.js浏览器打开
index.html,我们看到正确输出了我现在在使用Babel!然后我们打开打包后的
bundle.js,翻页到最下面,可以看到箭头函数被转换成普通函数了!Q:
babel-preset-state-0,babel-preset-state-1,babel-preset-state-2,babel-preset-state-3有什么区别?A: 每一级包含上一级的功能,比如
state-0包含state-1的功能,以此类推。state-0功能最全。具体可以看这篇文章:babel配置-各阶段的stage的区别参考地址:
https://segmentfault.com/a/1190000008159877
http://www.ruanyifeng.com/blog/2016/01/babel.html
npm install --save react react-dom修改
src/index.js使用react执行打包命令
webpack --config webpack.dev.config.js打开
index.html看效果。我们简单做下改进,把
Hello React放到组件里面。体现组件化~按照React语法,写一个Hello组件
然后让我们修改
src/index.js,引用Hello组件!src/index.js在根目录执行打包命令
webpack --config webpack.dev.config.js打开
index.html看效果咯~Q:每次打包都得在根目录执行这么一长串命令
webpack --config webpack.dev.config.js,能不打这么长吗?A:修改
package.json里面的script,增加dev-build。package.json现在我们打包只需要执行
npm run dev-build就可以啦!参考地址:
http://www.ruanyifeng.com/blog/2016/10/npm_scripts.html
npm install --save react-router-dom新建
router文件夹和组件按照
react-router文档编辑一个最基本的router.js。包含两个页面home和page1。src/router/router.js新建页面文件夹
新建两个页面
Home,Page1填充内容:
src/pages/Home/Home.jsPage1.js
现在路由和页面建好了,我们在入口文件
src/index.js引用Router。修改
src/index.js现在执行打包命令
npm run dev-build。打开index.html查看效果啦!那么问题来了~我们发现点击‘首页’和‘Page1’没有反应。不要惊慌,这是正常的。
我们之前一直用这个路径访问
index.html,类似这样:file:///F:/react/react-family/dist/index.html。这种路径了,不是我们想象中的路由那样的路径
http://localhost:3000~我们需要配置一个简单的WEB服务器,指向index.html~有下面两种方法来实现Nginx,Apache,IIS等配置启动一个简单的的WEB服务器。webpack-dev-server来配置启动WEB服务器。下一节,我们来使用第二种方法启动服务器。这一节的DEMO,先放这里。
参考地址
http://www.jianshu.com/p/e3adc9b5f75c
http://reacttraining.cn/web/guides/quick-start
简单来说,
webpack-dev-server就是一个小型的静态文件服务器。使用它,可以为webpack打包生成的资源文件提供Web服务。npm install webpack-dev-server --save-dev修改
webpack.dev.config.js,增加webpack-dev-server的配置。webpack.dev.config.js现在执行
webpack-dev-server --config webpack.dev.config.js浏览器打开http://localhost:8080,OK,现在我们可以点击
首页,Page1了,看URL地址变化啦!我们看到
react-router已经成功了哦。Q:
--content-base是什么?A:
URL的根目录。如果不设定的话,默认指向项目根目录。重要提示:webpack-dev-server编译后的文件,都存储在内存中,我们并不能看见的。你可以删除之前遗留的文件
dist/bundle.js,仍然能正常打开网站!
每次执行
webpack-dev-server --config webpack.dev.config.js,要打很长的命令,我们修改package.json,增加script->start:下次执行
npm start就可以了。既然用到了
webpack-dev-server,我们就看看它的其他的配置项。看了之后,发现有几个我们可以用的。
console中打印彩色日志404响应都被替代为index.html。有什么用呢?你现在运行npm start,然后打开浏览器,访问http://localhost:8080,然后点击Page1到链接http://localhost:8080/page1,然后刷新页面试试。是不是发现刷新后
404了。为什么?dist文件夹里面并没有page1.html,当然会404了,所以我们需要配置historyApiFallback,让所有的404定位到index.html。host,默认是localhost。如果你希望服务器外部可以访问,指定如下:host: "0.0.0.0"。比如你用手机通过IP访问。Webpack的模块热替换特性。关于热模块替换,我下一小节专门讲解一下。8080端口。localhost:3000上有后端服务的话,你可以这样启用代理:根据这几个配置,修改下我们的
webpack-dev-server的配置~webpack.dev.config.jsCLI ONLY的需要在命令行中配置package.json现在我们执行
npm start看看效果。是不是看到打包的时候有百分比进度?在http://localhost:8080/page1页面刷新是不是没问题了?用手机通过局域网IP是否可以访问到网站?
参考地址:
到目前,当我们修改代码的时候,浏览器会自动刷新,不信你可以去试试。(如果你的不会刷新,看看这个调整文本编辑器)
我相信看这个教程的人,应该用过别人的框架。我们在修改代码的时候,浏览器不会刷新,只会更新自己修改的那一块。我们也要实现这个效果。
我们看下webpack模块热替换教程。
我们接下来要这么修改
package.json增加--hotsrc/index.js增加module.hot.accept(),如下。当模块更新的时候,通知index.js。src/index.js现在我们执行
npm start,打开浏览器,修改Home.js,看是不是不刷新页面的情况下,内容更新了?惊不惊喜?意不意外?做模块热替换,我们只改了几行代码,非常简单的。纸老虎一个~
现在我需要说明下我们命令行使用的
--hot,可以通过配置webpack.dev.config.js来替换,向文档上那样,修改下面三处。但我们还是用
--hot吧。下面的方式我们知道一下就行,我们不用。同样的效果。HRM配置其实有两种方式,一种CLI方式,一种Node.js API方式。我们用到的就是CLI方式,比较简单。Node.js API方式,就是建一个server.js等等,网上大部分教程都是这种方式,这里不做讲解了。你以为模块热替换到这里就结束了?no
nono~上面的配置对
react模块的支持不是很好哦。例如下面的
demo,当模块热替换的时候,state会重置,这不是我们想要的。修改
Home.js,增加计数statesrc/pages/Home/Home.js你可以测试一下,当我们修改代码的时候,
webpack在更新页面的时候,也把count初始为0了。为了在
react模块更新的同时,能保留state等页面中其他状态,我们需要引入react-hot-loader~Q: 请问
webpack-dev-server与react-hot-loader两者的热替换有什么区别?A: 区别在于
webpack-dev-server自己的--hot模式只能即时刷新页面,但状态保存不住。因为React有一些自己语法(JSX)是HotModuleReplacementPlugin搞不定的。而
react-hot-loader在--hot基础上做了额外的处理,来保证状态可以存下来。(来自segmentfault)下面我们来加入
react-hot-loader v3,安装依赖
npm install react-hot-loader@next --save-dev根据文档,
我们要做如下几个修改~
.babelrc增加react-hot-loader/babel.babelrc{ "presets": [ "es2015", "react", "stage-0" ], "plugins": [ "react-hot-loader/babel" ] }webpack.dev.config.js入口增加react-hot-loader/patchwebpack.dev.config.jssrc/index.js修改如下src/index.js现在,执行
npm start,试试。是不是修改页面的时候,state不更新了?参考文章:
做到这里,我们简单休息下。做下优化~
在之前写的代码中,我们引用组件,或者页面时候,写的是相对路径~
比如
src/router/router.js里面,引用Home.js的时候就用的相对路径webpack提供了一个别名配置,就是我们无论在哪个路径下,引用都可以这样
下面我们来配置下,修改
webpack.dev.config.js,增加别名~webpack.config.js然后我们把之前使用的绝对路径统统改掉。
src/router/router.jssrc/index.js我们这里约定,下面,我们会默认配置需要的别名路径,不再做重复的讲述哦。
接下来,我们就要就要就要集成
redux了。要对
redux有一个大概的认识,可以阅读阮一峰前辈的Redux 入门教程(一):基本用法如果要对
redux有一个非常详细的认识,我推荐阅读中文文档,写的非常好。读了这个教程,有一个非常深刻的感觉,redux并没有任何魔法。不要被各种关于 reducers, middleware, store 的演讲所蒙蔽 ---- Redux 实际是非常简单的。
当然,我这篇文章是写给新手的,如果看不懂上面的文章,或者不想看,没关系。先会用,多用用就知道原理了。
开始整代码!我们就做一个最简单的计数器。自增,自减,重置。
先安装
reduxnpm install --save redux初始化目录结构
先来写
action创建函数。通过action创建函数,可以创建action~src/redux/actions/counter.js再来写
reducer,reducer是一个纯函数,接收action和旧的state,生成新的state.src/redux/reducers/counter.js一个项目有很多的
reducers,我们要把他们整合到一起src/redux/reducers.js到这里,我们必须再理解下一句话。
reducer就是纯函数,接收state和action,然后返回一个新的state。看看上面的代码,无论是
combineReducers函数也好,还是reducer函数也好,都是接收state和action,返回更新后的
state。区别就是combineReducers函数是处理整棵树,reducer函数是处理树的某一点。接下来,我们要创建一个
store。前面我们可以使用
action来描述“发生了什么”,使用action创建函数来返回action。还可以使用
reducers来根据action更新state。那我们如何提交
action?提交的时候,怎么才能触发reducers呢?store就是把它们联系到一起的对象。store有以下职责:state;getState()方法获取state;dispatch(action)触发reducers方法更新state;subscribe(listener)注册监听器;subscribe(listener)返回的函数注销监听器。src/redux/store.js到现在为止,我们已经可以使用
redux了~下面我们就简单的测试下
src/redux/testRedux.js当前文件夹执行命令
是不是看到输出了
state变化?做这个测试,就是为了告诉大家,
redux和react没关系,虽说他俩能合作。到这里,我建议你再理下
redux的数据流,看看这里。store.dispatch(action)提交action。redux store调用传入的reducer函数。把当前的state和action传进去。reducer应该把多个子reducer输出合并成一个单一的state树。Redux store保存了根reducer返回的完整state树。就是酱紫~~
这会
webpack.dev.config.js路径别名增加一下,后面好写了。webpack.config.jsalias: { ... actions: path.join(__dirname, 'src/redux/actions'), reducers: path.join(__dirname, 'src/redux/reducers'), redux: path.join(__dirname, 'src/redux') }把前面的相对路径都改改。
下面我们开始搭配
react使用。写一个
Counter页面src/pages/Counter/Counter.js修改路由,增加
Countersrc/router/router.jsnpm start看看效果。下一步,我们让
Counter组件和Redux联合起来。使Counter能获得到Redux的state,并且能发射action。当然我们可以使用刚才测试
testRedux的方法,手动监听~手动引入store~但是这肯定很麻烦哦。react-redux提供了一个方法connect。connect接收两个参数,一个mapStateToProps,就是把redux的state,转为组件的Props,还有一个参数是mapDispatchToprops,就是把发射
actions的方法,转为Props属性函数。先来安装
react-reduxnpm install --save react-reduxsrc/pages/Counter/Counter.js下面我们要传入
storesrc/index.js到这里我们就可以执行
npm start,打开localhost:8080/counter看效果了。但是你发现
npm start一直报错WTF?这个错误困扰了半天。我说下为什么造成这个错误。我们引用
redux的时候这样用的import {createStore} from 'redux'然而,我们在
webapck.dev.config.js里面这样配置了然后
webapck编译的时候碰到redux都去src/redux去找了。但是找不到啊。所以我们把webpack.dev.config.js里面redux这一行删除了,就好了。并且把使用我们自己使用
redux文件夹的地方改成相对路径哦。现在你可以
npm start去看效果了。这里我们再缕下(可以读React 实践心得:react-redux 之 connect 方法详解)
Provider组件是让所有的组件可以访问到store。不用手动去传。也不用手动去监听。connect函数作用是从Redux state树中读取部分数据,并通过 props 来把这些数据提供给要渲染的组件。也传递dispatch(action)函数到props。接下来,我们要说异步
action参考地址: http://cn.redux.js.org/docs/advanced/AsyncActions.html
想象一下我们调用一个异步
get请求去后台请求数据:isLoading置为true。isLoading置为false,data填充数据。isLoading置为false,显示错误信息。下面,我们以向后台请求用户基本信息为例。
user.json,等会请求用,相当于后台的API接口。dist/api/user.json{ "name": "brickspert", "intro": "please give me a star" }action创建函数。src/redux/actions/userInfo.js我们创建了请求中,请求成功,请求失败三个
action创建函数。reducer再强调下,
reducer是根据state和action生成新state的纯函数。src/redux/reducers/userInfo.js这里的
...state语法,是和别人的Object.assign()起同一个作用,合并新旧state。我们这里是没效果的,但是我建议都写上这个哦组合
reducersrc/redux/reducers.js现在有了
action,有了reducer,我们就需要调用把action里面的三个action函数和网络请求结合起来。dispatch getUserInfoRequestdispatch getUserInfoSuccessdispatch getUserInfoFailsrc/redux/actions/userInfo.js增加我们这里发现,别的
action创建函数都是返回action对象:{type: xxxx}但是我们现在的这个
action创建函数getUserInfo则是返回函数了。为了让
action创建函数除了返回action对象外,还可以返回函数,我们需要引用redux-thunk。npm install --save redux-thunk这里涉及到
redux中间件middleware,我后面会讲到的。你也可以读这里Middleware。简单的说,中间件就是
action在到达reducer,先经过中间件处理。我们之前知道reducer能处理的action只有这样的{type:xxx},所以我们使用中间件来处理函数形式的
action,把他们转为标准的action给reducer。这是redux-thunk的作用。使用
redux-thunk中间件我们来引入
redux-thunk中间件src/redux/store.js到这里,
redux这边OK了,我们来写个组件验证下。src/pages/UserInfo/UserInfo.js这里你可能发现
connect参数写法不一样了,mapStateToProps函数用了es6简写,mapDispatchToProps用了react-redux提供的简单写法。增加路由
src/router/router.js现在你可以执行
npm start去看效果啦!到这里
redux集成基本告一段落了,后面我们还会有一些优化。combinReducers优化
redux提供了一个combineReducers函数来合并reducer,不用我们自己合并哦。写起来简单,但是意思和我们自己写的
combinReducers也是一样的。src/redux/reducers.js现在我们发现一个问题,代码哪里写错了,浏览器报错只报在
build.js第几行。这让我们分析错误无从下手。看这里。
我们增加
webpack配置devtool!src/webpack.dev.config.js增加这次看错误信息是不是提示的很详细了?
同时,我们在
srouce里面能看到我们写的代码,也能打断点调试哦~先说这里为什么不用
scss,因为Windows使用node-sass,需要先安装 Microsoft Windows SDK for Windows 7 and .NET Framework 4。我怕有些人copy这份代码后,没注意,运行不起来。所以这里不用
scss了,如果需要,自行编译哦。npm install css-loader style-loader --save-devcss-loader使你能够使用类似@import和url(...)的方法实现require()的功能;style-loader将所有的计算后的样式加入页面中; 二者组合在一起使你能够把样式表嵌入webpack打包后的JS文件中。webpack.dev.config.jsrules增加{ test: /\.css$/, use: ['style-loader', 'css-loader'] }我们用
Page1页面来测试下src/pages/Page1/Page1.csssrc/pages/Page1/Page1.js好了,现在
npm start去看效果吧。npm install --save-dev url-loader file-loaderwebpack.dev.config.jsrules增加{ test: /\.(png|jpg|gif)$/, use: [{ loader: 'url-loader', options: { limit: 8192 } }] }options limit 8192意思是,小于等于8K的图片会被转成base64编码,直接插入HTML中,减少HTTP请求。我们来用
Page1测试下给
images文件夹放一个图片。修改代码,引用图片
src/pages/Page1/Page1.js可以去看看效果啦。
为什么要实现按需加载?
我们现在看到,打包完后,所有页面只生成了一个
build.js,当我们首屏加载的时候,就会很慢。因为他也下载了别的页面的js了哦。如果每个页面都打包了自己单独的JS,在进入自己页面的时候才加载对应的js,那首屏加载就会快很多哦。
在
react-router 2.0时代, 按需加载需要用到的最关键的一个函数,就是require.ensure(),它是按需加载能够实现的核心。在4.0版本,官方放弃了这种处理按需加载的方式,选择了一个更加简洁的处理方式。
传送门
根据官方示例,我们开搞
npm install bundle-loader --save-dev新建
bundle.jssrc/router/Bundle.jssrc/router/router.js现在你可以
npm start,打开浏览器,看是不是进入新的页面,都会加载自己的JS的~但是你可能发现,名字都是
0.bundle.js这样子的,这分不清楚是哪个页面的js呀!我们修改下
webpack.dev.config.js,加个chunkFilename。chunkFilename是除了entry定义的入口js之外的js~现在你运行发现名字变成
home.js,这样的了。棒棒哒!那么问题来了
home是在哪里设置的?webpack怎么知道他叫home?其实在这里我们定义了,
router.js里面import Home from 'bundle-loader?lazy&name=home!pages/Home/Home';看到没。这里有个
name=home。嘿嘿。参考地址:
想象一下这个场景~
我们网站上线了,用户第一次访问首页,下载了
home.js,第二次访问又下载了home.js~这肯定不行呀,所以我们一般都会做一个缓存,用户下载一次
home.js后,第二次就不下载了。有一天,我们更新了
home.js,但是用户不知道呀,用户还是使用本地旧的home.js。出问题了~怎么解决?每次代码更新后,打包生成的名字不一样。比如第一次叫
home.a.js,第二次叫home.b.js。文档看这里
我们照着文档来
webpack.dev.config.js每次打包都用增加
hash~现在我们试试,是不是修改了文件,打包后相应的文件名字就变啦?
但是你可能发现了,网页打开报错了~因为你
dist/index.html里面引用js名字还是bundle.js老名字啊,改成新的名字就可以啦。啊~那岂不是我每次编译打包,都得去改一下js名字?欲知后事如何,且看下节分享。
这个插件,每次会自动把js插入到你的模板
index.html里面去。npm install html-webpack-plugin --save-dev新建模板
index.htmlsrc/index.html修改
webpack.dev.config.js,增加pluginnpm start运行项目,看看是不是能正常访问啦。~说明一下:
npm start打包后的文件存在内存中,你看不到的。~ 你可以把遗留dist/index.html删除掉了。想象一下,我们的主文件,原来的
bundle.js里面是不是包含了react,redux,react-router等等这些代码??这些代码基本上不会改变的。但是,他们合并在
bundle.js里面,每次项目发布,重新请求bundle.js的时候,相当于重新请求了react等这些公共库。浪费了~我们把
react这些不会改变的公共库提取出来,用户缓存下来。从此以后,用户再也不用下载这些库了,无论是否发布项目。嘻嘻。webpack文档给了教程,看这里webpack.dev.config.js把
react等库生成打包到vendor.hash.js里面去。但是你现在可能发现编译生成的文件
app.[hash].js和vendor.[hash].js生成的hash一样的,这里是个问题,因为呀,你每次修改代码,都会导致vendor.[hash].js名字改变,那我们提取出来的意义也就没了。其实文档上写的很清楚,但是无奈,如果用
chunkhash,会报错。和webpack-dev-server --hot不兼容,具体看这里。现在我们在配置开发版配置文件,就向
webpack-dev-server妥协,因为我们要用他。问题先放这里,等会我们配置正式版webpack.config.js的时候要解决这个问题。文档看这里
我们要开始做了~
在
webpack.dev.config.js的基础上先做以下几个修改~webpack-dev-server相关的东西~devtool的值改成cheap-module-source-maphash改成chunkhashwebpack.config.js在
package.json增加打包脚本"build":"webpack --config webpack.config.js"然后执行
npm run build~看看dist文件夹是不是生成了我们发布要用的所有文件哦?接下来我们还是要优化正式版配置文件~
webpack使用UglifyJSPlugin来压缩生成的文件。npm i --save-dev uglifyjs-webpack-pluginwebpack.config.jsnpm run build发现打包文件大小减小了好多。webpack.config.jsnpm run build后发现vendor.[hash].js又变小了。刚才我们把
[name].[hash].js变成[name].[chunkhash].js后,npm run build后,发现
app.xxx.js和vendor.xxx.js不一样了哦。但是现在又有一个问题了。
你随便修改代码一处,例如
Home.js,随便改变个字,你发现home.xxx.js名字变化的同时,vendor.xxx.js名字也变了。这不行啊。这和没拆分不是一样一样了吗?我们本意是vendor.xxx.js名字永久不变,一直缓存在用户本地的。~
官方文档推荐了一个插件HashedModuleIdsPlugin
现在你打包,修改代码再试试,是不是名字不变啦?错了,现在打包,我发现名字还是变了,经过比对文档,我发现还要加一个
runtime代码抽取,加上这句话就好了~为什么呢?看下解释。
注意,引入顺序在这里很重要。CommonsChunkPlugin 的 'vendor' 实例,必须在 'runtime' 实例之前引入。
想象一个场景,我们的静态文件放在了单独的静态服务器上去了,那我们打包的时候,如何让静态文件的链接定位到静态服务器呢?
看文档Public Path
webpack.config.jsoutput中增加一个publicPath,我们当前用/,相对于当前路径,如果你要改成别的url,就改这里就好了。你现在打开
dist,是不是发现好多好多文件,每次打包后的文件在这里混合了?我们希望每次打包前自动清理下dist文件。npm install clean-webpack-plugin --save-devwebpack.config.js现在
npm run bundle试试,是不是之前的都清空了。当然我们之前的api文件夹也被清空了,不过没关系哦~本来就是测试用的。目前我们的
css是直接打包进js里面的,我们希望能单独生成css文件。我们使用extract-text-webpack-plugin来实现。
npm install --save-dev extract-text-webpack-pluginwebpack.config.jsnpm run build后发现单独生成了css文件哦axios和middleware优化API请求先安装下axios
npm install --save axios我们之前项目的一次API请求是这样写的哦~
action创建函数是这样的。比我们现在写的fetch简单多了。然后在dispatch(getUserInfo())后,通过
redux中间件来处理请求逻辑。中间件的教程看这里
我们想想中间件的逻辑
dispatchREQUEST请求。dispatchSUCCESS请求,如果定义了afterSuccess()函数,调用它。dispatchFAIL请求。来写一个
src/redux/middleware/promiseMiddleware.js修改
src/redux/store.js来应用这个中间件修改
src/redux/actions/userInfo.js是不是简单清新很多啦?
修改
src/redux/reducers/userInfo.jsaction.userInfo修改成了action.result.data。你看中间件,请求成功,会给action增加一个result字段来存储响应结果哦~不用手动传了。npm start看看我们的网络请求是不是正常哦。使用自动编译代码时,可能会在保存文件时遇到一些问题。某些编辑器具有“安全写入”功能,可能会影响重新编译。
要在一些常见的编辑器中禁用此功能,请查看以下列表: