不管在什么地方上班,请记住,工作不养闲人,团队不养懒人。没有哪个行业的钱是好赚的。赚不到钱,赚知识;赚不到知识,赚经历;赚不到经历,赚阅历!只有先改变自己的态度,才能改变人生的高度。让人迷茫的原因只有一个,那就是本该拼搏的年纪,却想得太多,做得太少。
前言:
凡事最怕认真,坚持下来了,你才会成为你心中的王者。本期已经到第七章了,如果你从第一期认真看到这里,那么你已经慢慢开始有了 React 的感觉了。
今天我们来聊聊 React 一般是如何跟服务端通信的,有后端通信的应用才算是一个真正有灵魂的应用,精彩内容不容错过!
正文:
章节:《深入浅出 React 和 Redux》(第七章:Redux 和服务器通信)
1.React 有两种访问服务器的方式
A:React 组件访问服务器的方式
B:React 架构下访问服务器的方式
2.React 组件访问服务器的方式适用于简单的页面应用;对于复杂的网页应用,自然会采用 Redux 来管理数据。
3. 解决跨域访问 API 的一个方式就是通过代理(Proxy),让我们的网页应用访问所属域名下的一个服务器 API 接口,这个服务器接口做的工作就是把这个请求转发给另一个域名下的 API,拿到结果之后再交给发起请求的浏览器网页应用,只是一个“代理”工作
4. 因为对于跨域访问 API 的限制是针对浏览器的行为,服务器对任何域名下的 API 的访问不受限制,所以这样的代理工作可以成功实现对跨域资源的访问
5. 在 weather_react 应用的根目录 package.json 中添加如下一行:
“proxy”:”http://www.weather.com.cn/”
这一行配置告诉 weather_react 应用,当接收到不是要求本地资源的 HTTP 请求时,这个 HTTP 请求的协议和域名部分替换为 http://www.weather.com.cn/ 转 …,并将收到的结果返还给浏览器,这样就实现了代理功能
6. 在 componentDidMount 函数中发送对服务器请求是一个合适的时机
7. 对任何输入输出操作只要记住一点:不要相信任何返回结果
8.React 组件访问服务器的优缺点,通过上面的例子,我们可以感受到让 React 组件自己负责访问服务器的操作非常直接简单,容易理解。对于想 Weather 这样的简单组件,代码也非常清晰。但是,把状态存放在组件中其实并不是一个很好的选择,尤其是当组件变得庞大复杂了之后
9.Redux 是用来帮助管理应用状态的,应该尽量把状态存放在 Redux Store 的状态中,而不是放在 React 组件中。同样,访问服务器的操作应该经由 Redux 来完成
10. 使用 Redux 访问服务器,同样要解决的是异步问题。可以使用 redux-thunk 中间件
npm install –save redux-thunk
11. 实际上,redux-thunk 的实现极其简单,只有几行代码,将它作为一个独立的 npm 发布而不是放在 Redux 框架中,更多的只是为了保持 Redux 框架的中立性,因为 Redux-thunk 只是 Redux 中异步操作的解决方法之一,还有很多其他的方法,具体使用哪种方法开发人员可以自行决定。
12. 前面例子中的 action 构造函数返回的都是一个普通的对象,这个对象包含若干字段,其中必不可少的字段是 type,但是“异步 action 对象”不是一个普通 JavaScript 对象,而是一个函数
13.redux-thunk 的工作是检查 action 对象是不是函数,如果不是函数就放行,完成普通 action 对象的生命周期,而如果发现 action 对象是函数,那就执行这个函数,并把 Store 的 dispatch 函数和 getState 函数作为参数传递到函数中去,处理过程到此为止,不会让这个异步 action 对象继续往前派发到 reducer 函数
14. 异步 action 构造函数 incrementAsync 返回的是一个新的函数,这样一个函数被 dispatch 函数派发之后,会被 redux-thunk 中间件执行,于是 setTimeout 函数就会发生作用,在 1 秒之后利用参数 dispatch 函数派发出同步 action 构造函数 increment 的结果。
15. 这就是异步 action 的工作机理,这个例子虽然简单,但是可以看得出来,异步 action 最终还是要产生同步 action 派发才能对 Redux 系统产生影响。
16. 一个访问服务器的 action,至少要设计三个 action 类型
A: 表示异步操作已经开始的 action 类型,在这个例子,表示一个请求天气信息的 API 请求以及发送给服务器的状态
B: 表示异步操作成功的 action 类型,请求天气信息的 API 调用获取了正确结果,就会引发这种类型的 action
C: 表示异步操作失败的 action 类型,请求天气信息的 API 调用任何一个环节出了错误,无论是网络错误、本地代理服务器错误或者是远程服务器返回的结果错误,都会引发这个类型的 action。
17. 当这三种类型的 action 对象被派发时,会让 React 组件进入各自不同的三种状态
A: 异步操作正在进行中
B: 异步操作已经成功完成
C: 异步操作已经失败
18. 异步操作的中止,在 jQuery 中,可以通过 abort 方法取消掉一个 AJAX 请求:
const xhr = $.ajax(…);
xhr.abort(); 取消掉已经发出的 AJAX 请求
19. 但是,很不幸,对于 fetch 没有对应 abort 函数的功能。我们有个技巧,就是在 action 构造函数文件中定义一个文件模块级的 nextSeqId 变量,这是一个递增的整数数字,给每一个访问 API 的请求做序列编号。
20. 在 fetchWeather 返回的函数中,fetch 开始一个异步请求之前,先给 nextSeqId 自增加一,然后自增的结果赋值给一个局部变量 seqId,这个 seqId 的值就是这一次异步请求的编号,如果随后还有 fetchWeather 构造器被调用,那么 nextSeqId 也会自增,新的异步请求会分配为新的 seqId。
21. 然后,action 构造函数中所有的 dispatch 函数都会替换为一个新定义的函数 dispatchIfValid,这个 dispatchIfValid 函数要检查一下当前环境的 seqId 是否等同于全局的 nextSeqId。如果相同,就说明 fetchWeather 没有被再次调用,就继续使用 dispatch 函数。如果不相同,说明这期间有新的 fetchWeather 被调用,也就是有新的访问服务器的请求被发出去了,这时候当前 seqId 代表的请求就已经过时了,直接丢弃掉,不需要 dispatch 任何 action。
22. 虽然不能真正“中止”一个 API 请求,但是我们可以用这种方法让一个 API 请求的结果被忽略,达到了中止一个 API 请求一样的效果。
23. 如果挑选异步操作方式
A: 在 Redux 的单向数据流中,什么时机插入异步操作?(Redux 的数据流转完全靠 action 来驱动,图 7 - 2 显示了数据流装的过程,对于 redux-thunk,切入异步操作的时机是在中间件中,但是这不是唯一的位置)
B: 对应库的大小如何?
C: 学习曲线是不是太陡?
D: 是否会和其他 Redux 库冲突?
24. 相对而言,虽然 redux-thunk 容易产生代码臃肿的问题,但真的是简单又易用,库也不大,只有几行代码而已。
25. 利用 Promise 实现异步操作。除了 redux-thunk,还有另一种异步模式,将 Promise 作为特殊处理的异步 action 对象,这种方案比 redux-thunk 更加易用,复杂度也不高。
26.fetch 函数返回的结果也是一个 Promise 对象,用 Promise 来连接访问 API 操作和 Redux,是天作之合。
27. 不过,对于 Promise 在 Redux 中应该如何使用,也没有形成统一观点,相关的库也很多,但是都很简单,用一个 Redux 中间件就足够实现。如:
A:redux-promise
B:redux-promises(名字只比上面的多一个表示复数的 s)
C:redux-simple-promise
D:redux-promise-middleware
等等
28. 无论是从服务器获取数据,还是想服务器提交数据,都是一个异步的过程。在一个 React 组件中,我们可以利用 componentDidMount,在装载过程结束时发起对服务器的请求来获取数据填充组件的内容。
观后感回放:
粉丝路人甲:“妈妈,我感觉我变秃了!也变强了!!”
锵哥:“编程是种技能也是种生活方式,锵哥建议努力学习也要努力保持身体健康,丢了 1 要后面的零毫无意义。”
粉丝路人甲:“锵哥,你太让我感动了,我还以为你又要喂我毒鸡汤了”
锵哥:“不喝了,游游泳,跑跑步吧,一起做个健康阳光的 IT 精英!”
粉丝路人甲:“????????????”
广告:
本人从事全栈工程师,目前主要工作能力涵盖的范围有:android,ios,h5,pcWeb,react,vue,node,java 服务端,微信服务号,微信小程序,支付宝生活号,支付宝小程序。
本公众号会不定期的将自己的研发感悟,以及心得笔记无私奉献给大家。还等啥,赶快上车吧,铁子们!!!????(还会有其他的福利哦!快来吧)
官方订阅号:锵哥的觉悟
微信号:DY_suixincq
二维码: