使用Flux的几个问题

最近使用react进行项目开发的时候遇到了几个比较纠结的问题,记录下来大家可以看看,
自己也可以慢慢研究,或者有哪位大神有什么好的解决方案,可以留个言或者发个邮件给我

异步操作结果处理

最简单的例子就是我们进行登录,我们需要输入用户名密码,并发送一个请求到服务器,等待服务器的返回结果,如果正确,我们跳转到登录成功页面,失败则跳转到登录失败页面。

换到flux里面,可能就是以下几个步骤:

  1. 在登录组件内输入用户名密码
  2. 点击登录按钮后dispatch一个action声明一下我要进行登录了
  3. action里面跟服务器进行沟通,获取是否登录成功的结果
  4. 如果成功,触发一个登录成功的action,如果失败,触发一下登录失败的action
  5. 然后store根据不同的action结果,渲染不同的结果

这看起来貌似非常正常的一个流程,从组建操作,到动作触发,再到数据确认,最后重新渲染。

但是,如果我们追究到细节,就会提出一个问题:

登录组件如何知道登录是否成功?

我们会有这个问题是因为这是一个单页面应用,所以在进行异步请求的时候我们肯定就要维护不同的状态,试想我们不适用react进行开发,
而是使用jQuery我们会怎么做。我们就会绑定一个submit事件到form上,form在提交的时候我们获取事件,读取form表单的数据,通过ajax发送请求,
然后我们再发送ajax之前我们先把登录按钮disable掉,并且还可以改文字为正在登录...,然后ajax请求结束之后,
根据不同的结果我们可以修改取消登录按钮的disable状态,然后把文字改回来,或者登录成功直接跳转到新的view上面。

而在flux下,我们在点击按钮之后操作就交给action,在当前组件的上下文当中我们没办法知道action进行到哪一步了,唯一知道的办法是通过action改变store里面的状态。
我们可以想象在我们的user store里面加上几个状态{syncing: true, success: true, error: false}

这似乎解决我们的问题,但仔细一想,似乎又有些不对(ˇˍˇ) 。如果我们把success, error这样的状态放到一个store里面,如果有其他的组件也要使用这个store,那么这个状态也就一起过去了。
但是我们仔细想一想,这个状态应该是这次action的状态,这并不应该一个store的状态,我们放在store里面的数据应该是非常慎重的,是在整个app下面都通用的状态,
对于一个store我们可以有非常多的action,如果每个action都需要不同的状态,那么当app非常大之后,我们就没犯法很好得维护这些状态。

当然如果我们要解决也是很好解决的,我们可以给action加上两个callback

但是这是违背flux的单向数据量的原则。

思考

我提出上面的例子,似乎很大程度上是因为我还没有从老式的MVC模式中走出来。借此机会我再来好好理解一下flux

fb当初提出flux的时候有这么一个设想,他们联系以前老式的网站开发的模式,前端提交一个请求到后端,后端根据请求处理数据,然后根据结果渲染好对应的HTML,返回给浏览器,然后给浏览器展示。
这整个过程实际上跟fluxcomponent --> action --> store -(props)-> component的流程很相似。那么在这里action其实就是一个http请求处理程序,store是一个数据集(数据库)存储数据

那么action应该做的事情就是根据请求告诉store应该如何进行数据更新,在老式的服务器渲染的开发模式中浏览器在发送请求之后就直接等待服务器发送的HTML了,
所以在这里组件发送action之后也是不应该有状态回馈的(除了syncing状态,类比浏览器请求中的情况)。

那么最终如何决定请求结束后页面该以什么形态展示呢?

是URL

我们可以看到传统的网站url是经常在变动的,登录,表单提交,查看列表,每个请求其实就对应一个URL,换句话说,URL表明了我们以什么样的方式展现我们的网站