再見了 Redux (翻譯)

作者:Jack Scott

原文 國內(nèi)網(wǎng)可能訪問不到……大致翻譯如下:

本文主要分析了一下我們過去為什么需要 Redux吱晒,而為什么以后又不再需要了财著。

Goodbye Redux

在過去的幾年里联四,互聯(lián)網(wǎng)技術(shù)已經(jīng)轉(zhuǎn)向用前端 JavaScript 框架來實現(xiàn)網(wǎng)站和手機應用,以達到更好的用戶體驗撑教。這非常棒 ?? 朝墩,我個人很欣賞這些框架提供的靈活性。

但是靈活得是否有些過頭了……

為了能更好地理解這個問題伟姐,讓我們把時鐘撥回到 JavaScript 框架出現(xiàn)以前收苏,看看我們是怎么開發(fā)應用的亿卤。

? JavaScript 以前的大陸 A Land Before JavaScript…

在前幾個前端框架(最值得注意的是AngularJS、Backbone和Ember)出現(xiàn)之前鹿霸,我們只是在服務(wù)器上渲染模板怠噪,然后將完整的HTML頁面發(fā)送到瀏覽器。當時流行的框架包括:

sf, django, rails
  • Django (Python)——2005年7月21日發(fā)布 ~13 年前
  • Ruby on Rails?——?2005年12月13日發(fā)布 ~13 年前
  • Symphony (PHP)?——?2005年10月22日發(fā)布 ~13 年前

這些框架主要是圍繞了 MVC 概念也就是 Model-View-Controller 來開發(fā)的杜跷,Model 表示數(shù)據(jù)的模型,View 表示怎么顯示這些數(shù)據(jù)矫夷,而 Controller 則連接這兩部分葛闷。

我的意思是說,這其中也有 JavaScript双藕,但我們更多的時候是在說 jQuery 做的滑動條和一些完全沒必要的動態(tài)網(wǎng)頁效果

在這些框架上編寫的應用有一些問題淑趾,但總得來說還不錯,直到有一天 Ryan Dahl 有了一個很棒的主意忧陪,他開發(fā)了第一版的 Node.js扣泊,可以讓開發(fā)人員寫服務(wù)端程序,而不止是用 JavaScript 做些愚蠢的動畫嘶摊。

  • Node.js ——2009年5月27日發(fā)布 ~9 年前

猛然間人們似乎看到了 JavaScript 的無限可能性延蟹,用一丁點兒的代碼就能做很多事兒,這充分打開了其他開發(fā)人員的想象力叶堆,人們不僅創(chuàng)建更多強大的 Node.js 工具阱飘,還開始創(chuàng)建有趣的前端框架,在接下來的幾年里虱颗,JavaScript 就象滾雪球一樣高速發(fā)展起來:

AngularJS, Backbone.js, Ember.js
  • Express.js(后端)——2010年11月16日發(fā)布 ~8 年前
  • Backbone.js(前端)——2010年10月12日發(fā)布 ~8 年前
  • AngularJS(前端)——2010年10月20日發(fā)布 ~8 年前
  • Ember.js(前端)——2011年12月8日發(fā)布 ~8 年前

這就開始了應用開發(fā)模式的重大轉(zhuǎn)變沥匈。之前由服務(wù)端直接處理的 MVC 模式被分拆為兩部分:一個服務(wù)端的 MC 和一個客戶端的 V(MC),客戶端使用的就是上述的前端框架忘渔。在早期的這些框架中高帖,還包含 Model 和 Controller 層在 View 中。兩份 Model 和 Controller畦粮,前端也有一份 MC散址,這樣看來是要寫更多的代碼了。

??? 臉書有個頭疼的問題 Facebook Had A Problem

正當所有人開心地使用上述方案的時候宣赔,F(xiàn)acebook 來了爪飘,隨著它的迅速崛起,F(xiàn)acebook 變成了最大的網(wǎng)頁應用拉背,而為了解決頁頭上即時消息的數(shù)量顯示問題(實際上這個小問題在海量用戶使用的場景下是比較復雜的)师崎,舊的方案也并不能很好地應對……

Facebook head aches

于是他們推出了 React:

  • React(前端)?——2013年?三月發(fā)布 ~5 年前

而 React 只管 View 層,于是又有了 Flux椅棺,之后是 Redux(Redo Flux)犁罩,有興趣了解詳情的可以看這個視頻:

Youku視頻 QQ視頻

?? ……于是這東西變得象個鴨梨 …Then Things Started to Go Pear Shaped

Redux 的工作方式是把一個應用中幾乎所有的動態(tài)信息都保存在一個 JavaScript 對象中齐蔽。這樣不管你在應用的哪個地方看到的數(shù)據(jù)都來自同一個地方,也就能保持一致床估,這樣也就解決了 Facebook 所頭疼的問題含滴。

于是突然又來了一種新框架:React + Redux 解決方案,F(xiàn)acebook 用它來解決問題丐巫,而從此以后所有人都過上了幸福的生活……對嗎谈况?

? 不盡然 Not quite.

問題在于人們(包括我)開始用一個對象保存所有信息,其中的每一部分都是由服務(wù)端獲得递胧,沒錯這可以保證數(shù)據(jù)的及時更新碑韵,但同時也存在 3 個缺點:

  1. 這需要大量的多余的代碼才能很好地運行,這很浪費時間缎脾。
  2. 因為所有代碼放在一處祝闻,這可能帶來“舊數(shù)據(jù)”的問題,也就是說你可能在應用中見到一些來自之前狀態(tài)的不想要的數(shù)據(jù)遗菠。
  3. 對于新的開發(fā)人員學習曲線太高联喘,繼而使得前端Web開發(fā)很難被新的開發(fā)人員采用。

我們有一個向用戶顯示數(shù)據(jù)的相對簡單的老式 MVC 框架應用辙纬,其中也就是幾個簡單的模板豁遭,在2005年,我們成功地將它轉(zhuǎn)換為一個單頁面應用贺拣,它的前端代碼通常是后端代碼的 10 倍堤框。例如:我最近開發(fā)了一個簡單的應用,然后我用 WakaTime 來衡量我在編碼上的耗時情況纵柿,以下是測量結(jié)果:

  • React Redux 前端代碼庫—— 32 小時.
  • Express + Mongoose 后端代碼庫——4 小時.

?? 你當真蜈抓?Are you serious??

我花了 8 倍的時間在前端?讓我們看看原因吧昂儒,下面是一個示例沟使,一個很普通的取數(shù)據(jù)(例如取得所有用戶)到前端的流程:

?? 警告:下面的步驟描述非常技術(shù)化,如果你看不太懂沒關(guān)系渊跋。Warning: the following steps are super techy so don't worry if you get lost.

  1. 創(chuàng)建一個組件來顯示用戶列表(這一步?jīng)]啥問題)腊嗡;
  2. 創(chuàng)建一個 fetch 請求到后端接口;
  3. state 中添加一個新字段拾酝;
  4. 添加一個 action 用來更新 state 的數(shù)據(jù)燕少;
  5. 添加一個 thunk 方法來運行 fetch 請求,然后使用新的 action 來更新 state 狀態(tài)蒿囤;
  6. 使用 connect() 將這個 thunk 方法加到組件中的 dispatch 方法中客们;
  7. 再次使用 connect()state 中提取數(shù)據(jù);
  8. 在組件的 prop types 屬性類型中聲明 thunk 方法和提取的數(shù)據(jù)字段;
  9. componentDidMount() 方法中調(diào)用 thunk 方法底挫;
  10. 最后恒傻,渲染數(shù)據(jù)到界面;

我的天……10步建邓,回到 Ruby on Rails 的時代盈厘,我只需要把數(shù)據(jù)放到 HTML 的模板中就完事兒了,達到的效果差不多官边,我想這中間肯定有什么問題吧沸手?!

?? 一條新的路徑 A New Approach

Redux 只是解決了前端數(shù)據(jù)的一致性注簿,但它也帶來了如前所述的問題契吉,那么它的價值到底是什么?

基本上我們重寫了整個前端只是解決了屈指可數(shù)的幾個小問題滩援。

Facebook 也意識到了這個問題,啟動了一個新項目叫 GraphQL塔嬉,GraphQL 目前還是個技術(shù)名詞玩徊,我不確定大家是否知道它為什么酷?

GraphQL 完全不同于 Redux谨究,F(xiàn)acebook 又創(chuàng)造了一個大神級的產(chǎn)品恩袱,但卻沒指出這寶貝為什么這么重要,這也是為什么我花時間寫此文的原因胶哲。

簡言之畔塔,如果說 Redux 是一匹馬的話,GraphQL 就是一輛車鸯屿。

什么澈吨?怎么 Redux 成了一匹馬?

我之所以把它們比做一匹馬和一輛車寄摆,原因是這倆完全是兩個物種谅辣,一個是有四條腿的馬動物,一個是有四個輪子的機器婶恼。然而桑阶,它們的作用是一樣的,都是把人運到想去的地方勾邦。雖然它們各自有不同的適合場景蚣录,但通常來說,汽車會更快些眷篇。

那么萎河,GraphQL 到底是什么?

官方文檔是這樣說的:“GraphQL 是一種 APIs 接口的查詢語言”,感覺不清不楚的公壤,其實他們所謂的查詢語言基本上一個就可以替代上百個 HTTP 接口换可,因為這個技術(shù)還很新,所以文檔和支持的技術(shù)還有點難懂厦幅,有一定的學習曲線沾鳄。這兒給你一個例子看是否有幫助:

GraphQL 可以替代類似這樣的接口:

  • GET /users/1234567890
  • POST /cars
  • PUT /example/endpoints

只查詢你需要的字段,如下:

{
  user(id: "1234567890") {
    name,
    email
  }
}

返回:

{
  "user": {
    "name": "Luke Skywalker",
    "email": "luke@iamyourfather.com"
  }
}

等一下——自定義的查詢……這可是需要點兒時間去實現(xiàn)的确憨,也許你這么認為~

但實際上不用译荞,原因在于:由于只請求需要的數(shù)據(jù),突然你不需要那么多服務(wù)端請求了休弃,也就是說你不需要寫那么多代碼去處理那么多服務(wù)端請求了吞歼,于是,你就節(jié)省了大量不需要實現(xiàn)的代碼和時間塔猾。

??? 但這就能替代 Redux 了嗎篙骡?But how does this replace Redux?

問得好!簡單地說丈甸,不能糯俗。不過,它鼓勵你不要象 Redux 那樣把所有信息存在一個單獨的對象中睦擂,因為每個查詢只針對應用的一小部分得湘,而不是整個應用。在一整個應用的數(shù)據(jù)源中只關(guān)注一小部分顿仇,這應該算是個 anti-pattern 反模式淘正、反常識(甚至是有點不合邏輯)的。

通過使用 GraphQL 你就可以擺脫對 Redux 的依賴從而省掉大量的代碼臼闻。

還有一點要注意:Redux 和 GraphQL 是可以共存的鸿吆,這樣你可以平滑地過渡,這兒有一些關(guān)于兩者整合的文章:

Integrating with Redux | Apollo React Docs

用不用 Redux 變成一種選擇述呐。是用它解決一些小任務(wù)而面對頭疼的問題伞剑,還是換一種方法完成那些任務(wù)?

那么市埋,你會怎么選擇黎泣?

Redux 在當時確實解決了問題,但就在同時缤谎,Web 開發(fā)行業(yè)又在 Web sockets 領(lǐng)域有了巨大的進步抒倚。

Web sockets 是在服務(wù)端和客戶端建立持續(xù)的連接,服務(wù)端就可以通知客戶端何時更新坷澡。你猜怎么著托呕?GraphQL 用一種叫 subscriptions 的訂閱技術(shù)直接就能支持 web sockets,我們可以用這種 subscriptions 的訂閱機制來更新應用中想保持同步的部分。

核心的區(qū)別在于:與其讓客戶端(用 Redux)告訴我們哪里要更新项郊,不如讓服務(wù)端直接通知客戶端更新馅扣。結(jié)果是一樣的,這兒有一些例子是怎么用 MongoDB 或 Mongoose 實現(xiàn) Web socket 和 subscriptions 的着降。

A Node.js Perspective on MongoDB 3.6: Change Streams

Mongoose v5.2.12: API?—?Model.watch()

?? 未來很精彩差油!The Future Looks Awesome!

GraphQL 開發(fā)沒多久,但眼下也可以用在產(chǎn)品上了任洞。我不想撒謊蓄喇,官方文檔確實能把人搞暈,需要對 JavaScript 和 服務(wù)端運行機制有很強的理解才行交掏。然而如果你還沒那么強妆偏,但想了解更多,這有一個很流行的教程:

GraphQL: A query language for APIs.

還有很多有用的庫可以幫你逐步地整合 GraphQL 到已有產(chǎn)品中盅弛。不用擔心钱骂,你不用一次弄完,這些庫可以幫你輕松地挪鹏、慢慢地改善你的應用见秽。Apollo 就是一家做這事兒的公司。

Apollo GraphQL

好了狰住,我希望這篇文章可以對闡明一些復雜的概念有幫助张吉。

如果你喜歡這篇文章齿梁,請點贊——這對我來說是很大的鼓勵——或者有問題請留言催植。

謝謝!??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勺择,一起剝皮案震驚了整個濱河市创南,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌省核,老刑警劉巖稿辙,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異气忠,居然都是意外死亡邻储,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門旧噪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吨娜,“玉大人,你說我怎么就攤上這事淘钟』略” “怎么了?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長勾扭。 經(jīng)常有香客問我毡琉,道長,這世上最難降的妖魔是什么妙色? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任桅滋,我火速辦了婚禮,結(jié)果婚禮上燎斩,老公的妹妹穿的比我還像新娘虱歪。我一直安慰自己,他們只是感情好栅表,可當我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布笋鄙。 她就那樣靜靜地躺著,像睡著了一般怪瓶。 火紅的嫁衣襯著肌膚如雪萧落。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天洗贰,我揣著相機與錄音找岖,去河邊找鬼。 笑死敛滋,一個胖子當著我的面吹牛许布,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播绎晃,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蜜唾,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了庶艾?” 一聲冷哼從身側(cè)響起袁余,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咱揍,沒想到半個月后颖榜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡煤裙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年掩完,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片硼砰。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡且蓬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出夺刑,到底是詐尸還是另有隱情缅疟,我是刑警寧澤分别,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站存淫,受9級特大地震影響耘斩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜桅咆,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一括授、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧岩饼,春花似錦荚虚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至寞冯,卻和暖如春渴析,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背吮龄。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工俭茧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人漓帚。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓母债,卻偏偏與公主長得像,于是被迫代替她去往敵國和親尝抖。 傳聞我的和親對象是個殘疾皇子毡们,可洞房花燭夜當晚...
    茶點故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容