Lots of people use React as the V in MVC. Since React makes no assumptions about the rest of your technology stack,it's easy to try it out on a small feature in an existing project.
我大致意译一下:React仅仅尝试解决关于UI的某一个方面(不是全部)的问题,它不来假设你使用了什么其它技术。它易于理解,可以在您已经存在的项目中尝试使用。背后的哲学是:我只做一件事(关于UI),并且把它做到极致。
这不是一篇叫你如何使用React的文章。它只是用react的方式思考一个问题,把它表达出来,如果您是业内人士,一定会用自己的技术栈和它作出对比。如果你这样做了,这篇文章的目的就达到了。
这是一个登陆页面,服务器一端提供restful形式的响应,这是一个单页面程序。服务器响应的数据结构如下,| 表示可能性:
{ state:ANONYMOUS|REMEMBER_ME|FULL,showCaptcha:true|false,message:WRONG_JSON_MESSAGE|USERNAME_PASSWORD_NOT_MATCH|UNKNOWN|SHOW_CAPTCHA|WRONG_CAPTCHA|NO_MESSAGE,user:null|{email:xxx@yyy},wtg:wheretogo }
客户端rest请求的表:
路径 | http方法 | content-type | 响应 |
/login | GET | * | 登陆页面HTML(静态) |
/login | POST | application/json | 上面提到的数据结构 |
/loginstatus | GET | * | 上面提到的数据结构 |
可能的用户操作流程:
用户可能中途刷新了浏览器,那么就和1一样了。
不管是哪种可能,我们都会获取一个数据。数据有许多不同的组合,我们把不同的组合叫做状态,react的核心就是状态(数据)和UI之间建立单向的联系。
下面来分析一下可能的状态:
1、用户打开登陆页面,此时通过/loginstatus获取的数据可能是:
{state:ANONYMOUS,message:NO_MESSAGE,showCaptcha:false}
{state:ANONYMOUS,message:USERNAME_PASSWORD_NOT_MATCH,showCaptcha:false}
{state:ANONYMOUS,showCaptcha:true}
此时开始,验证码字段显示。为什么说此时开始呢?即使你刷新了浏览器,还是会显示验证码字段。
state:FULL,showCaptcha:false,wtg:"http://哪里跌倒,哪里起来"}
此时客户端根据情况开始新的页面。
从整个过程来说,用react提倡的状态来思考,一切行为都通用化,没有什么特殊性。UI只是忠实的反应状态而已,至于是显示验证码,或提示用户名错误都一视同仁。
代码:
1、表单容器组件,主要是为登陆表单增加一些效果切换,比如页面初始打开时显示的是Loading,然后在请求登陆状态的时候显示"querying state",最后根据query结果,显示登陆表单。
varLoginFormContainer=React.createClass({ getInitialState:function(){ return{queryLoginState:true}; },componentDidMount:function(){ console.log(this.props.ucRestClient?"ucrestclientisset.":"noucrestclient"); varthat=this,restClient=this.props.ucRestClient; restClient.loginstate().then(function(response){ console.log('response:',response); that.setState({queryLoginState:false,entity:response.entity}); }); },render:function(){ varc; if(this.state.queryLoginState){ c=<p>queryLoginState....</p>; }else{ c=<LoginForm{...this.props}{...this.state.entity}/>; } return( <divclassName="login-form-container"> {c} </div> ); } });
2、表单组件:
varUserNameField=React.createClass({ componentDidMount:function(){ console.log(this.props.value);//=>true },render:function(){ return( <divclassName="pure-control-group"> <labelhtmlFor="username">Username</label> <inputname="username"value={this.props.value}type="text"placeholder="Username"/> </div>); } }); varPasswordField=React.createClass({ render:function(){ return( <divclassName="pure-control-group"> <labelhtmlFor="password">Password</label> <inputname="password"value={this.props.value}type="password"placeholder="Password"/> </div>); } }); varCaptchaField=React.createClass({ render:function(){ return( <divclassName="pure-control-group"> <labelhtmlFor="captcha">Captcha</label> <inputname="captcha"value={this.props.value}placeholder="Captcha"/> </div>); } }); varLoginForm=React.createClass({ getInitialState:function(){ return{}; },handleSubmit:function(e){ e.preventDefault(); if(this.state.submiting){ return; } varusername=this.state.username,password=this.state.password,captcha=this.state.captcha,ucClient=this.props.ucRestClient,that=this; varcanSubmit=true; if(!username||username.length<3){ canSubmit=false; } if(!password||password.length<6){ canSubmit=false; } if(this.state.showCaptcha){ if(!captcha||captcha.length!==5){ canSubmit=false; } } if(canSubmit){ this.setState({submiting:true}); ucClient.login({ username:username,password:password,captcha:captcha }).then(function(response){ console.log('response:',response); that.setState({submiting:false}); }); } },handleChange:function(e){ //DOMEventTarget,id,tagName varstateo={}; stateo[e.target.name]=event.target.value.trim(); this.setState(stateo); //console.log(e.target.value); },render:function(){ varcaptchaField; if(this.state.showCaptcha){ captchaField=<CaptchaFieldvalue={this.state.captcha}/>; } return( <formclassName="pure-formpure-form-aligned"action="/login"method="POST"onSubmit={this.handleSubmit}onChange={this.handleChange}> <fieldset> <UserNameFieldvalue={this.state.username}/> <PasswordFieldvalue={this.state.password}/> {captchaField} <divclassName="pure-controls"> <labelhtmlFor="cb"className="pure-checkBox"> <inputid="cb"type="checkBox"/>I'vereadthetermsandconditions </label> <buttontype="submit"className="pure-buttonpure-button-primary">Submit</button> </div> </fieldset> </form> ); } });
3、rest客户端工具代码:
'usestrict'; varrest,mime,csrf,client; rest=require('rest'); mime=require('rest/interceptor/mime'); csrf=require('rest/interceptor/csrf'); var_csrf=window.jQuery("Meta[name='_csrf']").attr("content"),_csrf_header=window.jQuery("Meta[name='_csrf_header']").attr("content"),ucclient=rest.wrap(mime,{mime:'application/json'}).wrap(csrf,{token:_csrf}); module.exports={ login:function(entity){ returnucclient({ path:'/login',method:"POST",entity:entity}); },loginstate:function(){ returnucclient({ path:'/loginstate',method:"GET" }); } };
注意:以上代码是本人在2天时间内(包括寻找开发环境的设置)通过阅读reactjs官方文档写作而成,可能会存在非常规的代码写法,请指正。
结论:以reactjs编写UI界面,逻辑非常简单明了,便于维护,强烈推荐尝试。