今天来聊聊前端,其实这个专题刚开始写起来的时候,是想和你们分享数据可视化的一些知识的。这也是图表君名头的由来,后来慢慢就写进了些前端的东西,再后来,由于图表君工做的转换,如今更多的作一些后台的工做,那么讨论的问题就更杂了,如今看起来算是个人一些工做和学习心得和感觉吧。javascript
好了,说了这么多。今天聊点什么呢?聊聊React。其实这也并非什么新东西了。2014年,图表君就知道有这么个东西,听着几位业界大牛聊,说这东西有多么多么的好,当时也不是特别的理解,跟了一遍官方的Tutorial,也没有特别的感觉。应该是由于当时前端的经验特别的浅(虽然如今也不敢说深,捂脸),没有什么特别的感觉吧。html
后来作了几个项目,使用的是Angular,刚开始以为双向数据绑定好牛逼啊,好好用,好好用。可是随着项目逐渐的一点点变大,感受$scope上的东西是愈来愈多,各个controller里各有各的$scope,再加上$scope是继承的,当项目一复杂就愈来愈难以管理和控制。还有本身要封装一个组件在angular里得用directive吧,好吧看看directive的文档你就得晕了,link,compile,controller都是什么鬼。好了,今天不是吐槽angular的时间,可是angular得设计和使用的确是太复杂了。前端
好了,让咱们先暂时跳出框架的讨论,来思考一下,前端的工做究竟是干什么的?其实能够简单的说就是将数据到View的一个映射上,也就是说不管什么框架解决的基本问题就是讲数据展现到View上, 而后将讲用户的操做最后再反应到数据的变化上来。java
Data --> Whatever FrameWork --> View Data <-- Whatever FrameWork <-- View
再想清楚这个问题以后,React是怎么作的呢?React并非一个完整的前端框架,只是一个专一于渲染View的library,在看了React的文档以后,咱们会发现他的api是很简单的。一个典型的react的组件react
class ShoppingList extends React.Component { render() { return ( <div className="shopping-list"> <h1>Shopping List for {this.props.name}</h1> <ul> <li>Instagram</li> <li>WhatsApp</li> <li>Oculus</li> </ul> </div> ); } } // Example usage: <ShoppingList name="Mark" />
即便你没有React的经验,看这样的代码也不会有什么特别的问题。好了,今天图表君不打算安利React,并不想写一个hello world出来。这样的文章太多,看看React的官方例子会比图表君写的好不少。那么今天说什么呢?git
看这部分以前,图表君强烈建议你能够看一看React的官方tutorialtutorial,很好的一个例子,也不长。一个小时就能看完,本身上手写一写,感觉会更深。好了如今假设你看完了这个tutorial有什么感受?github
图表君的最大的感觉是,最后将State,function都定义到了Game的这个Root级别的Component上了,再把全部的数据和function都传进本身的子Component里,须要的地方直接调用就行了。这样就使得咱们上边说把Data的操做逻辑都被提出来,并集中在一块儿了,一下就清晰了,明确了。App管理今后变得一下简单了。反复品味这样的设计,突然有个东西,进入了个人思惟里。这东西不就是一个有限状态机呀。api
有限状态机是个十分有用的模型,能够用来模拟世界上大部分的事物,其有三个特征:前端框架
状态总数(state)是有限的。框架
任一时刻,只处在一种状态之中。
某种条件下,会从一种状态转变(transition)到另外一种状态。
咱们再来看看例子中的代码
class Game extends React.Component { constructor(){ super(); this.state={ history:[{ squares: Array(9).fill(null) }], stepNumber: 0, xIsNext: true } } handleClick(i){ const history = this.state.history; const stepNumber = this.state.stepNumber const current = history[history.length - 1]; const squares = current.squares.slice(); if (calculateWinner(squares) || squares[i]) { return; } squares[i] = this.state.xIsNext? 'X':'O'; this.setState( { history: history.concat([{ squares: squares }]), stepNumber: stepNumber + 1, xIsNext: !this.state.xIsNext, } ) } jumpTo(step){ const newHistory = this.state.history.slice(0,step+1) console.log(newHistory); this.setState({ history: newHistory, stepNumber:step, xIsNext: (step % 2) ? false: true, }) } render() { const history = this.state.history; const current = history[this.state.stepNumber]; const winner = calculateWinner(current.squares); let status; if(winner){ status = 'Winner Is :' + winner; }else{ status = 'Next player: ' + (this.state.xIsNext ? 'X':'O'); } const moves = history.map((step,move) => { const desc = move ? 'Move #' + move : 'Game Start'; return( <li key={move}> <a href="#" onClick={() => this.jumpTo(move)}>{desc}</a> </li> ) }); return ( <div className="game"> <div className="game-board"> <Board squares={current.squares} onClick={(i) => this.handleClick(i)} /> </div> <div className="game-info"> <div>{status}</div> <ol>{moves}</ol> </div> </div> ); } }
构造方法,constructor - 定义了APP的初始状态。
handleClick - 定义了在棋盘里点击事件后的APP状态的变化。
jumpTo - 定义点击历史记录中某一步后APP的状态变化。
render- 描述如何在View上来展现当前的状态。
这样精巧的设计,facebook果真汇集了当今世界一流的工程师。而后我看了阮一峰的这篇介绍有限状态机的文章,看到这段代码。
var menu = { // 当前状态 currentState: 'hide', // 绑定事件 initialize: function() { var self = this; self.on("hover", self.transition); }, // 状态转换 transition: function(event){ switch(this.currentState) { case "hide": this.currentState = 'show'; doSomething(); break; case "show": this.currentState = 'hide'; doSomething(); break; default: console.log('Invalid State!'); break; } } };
有没有似曾相识的感受,Redux里是否是就是这么干的?而后再想一想Redux,到底干了一件什么事?帮咱们作了这样的一个状态机啊,咱们开发者只要定义Action,Reducer,他把咱们的APP组织成了一个状态机。
从这样的角度再来看React,Redux这个的技术栈,我以为理解的更加的清楚了,固然这仅仅是个人一点点小小的思考,欢迎你们一块儿讨论拍砖,后边逐步的和你们分享个人心得体会。