摘要:譯者按最近依舊如火如荼相信大家都躍躍欲試我們團(tuán)隊也開始在領(lǐng)域有所嘗試年應(yīng)該是逐漸走向成熟的一年讓我們一起來看看國外的開發(fā)者們都總結(jié)了哪些最佳實踐年在全世界都有很多關(guān)于新的更新和開發(fā)者大會的討論關(guān)于去年的重要事件請參考那么年最有趣的問題來了我
譯者按:最近React(web/native)依舊如火如荼,相信大家都躍躍欲試,我們團(tuán)隊也開始在React領(lǐng)域有所嘗試. 2016年應(yīng)該是
React 逐漸走向成熟的一年,讓我們一起來看看國外的開發(fā)者們都總結(jié)了哪些"最佳實踐".
2015年 React 在全世界都有很多關(guān)于新的更新和開發(fā)者大會的討論.關(guān)于去年的重要事件,請參考 React in 2015.
那么,2016年最有趣的問題來了:我們應(yīng)該如何開發(fā)一個 App, 有什么推薦的庫?
作為一名長期使用 React.js 的開發(fā)者,我對此問題有自己的答案和最佳實踐,但你可能不一定完全同意.我對你的想法和觀點很有興趣,請留言以便討論.
如果你剛剛開始接觸React.js,可以查看我們的 React.js 教程,或者 Pete Hunt 的 React howto.
數(shù)據(jù)處理在 React.js 應(yīng)用中處理數(shù)據(jù)非常簡單,但也充滿挑戰(zhàn).
這是因為你可以使用多種方式將屬性數(shù)據(jù)傳遞給 React 組件,從而構(gòu)建出渲染樹,但你應(yīng)該怎樣更新視圖卻不是顯而易見的.
2015一開始便誕生了很多不同 Flux 庫,隨后涌現(xiàn)出出更多具有更強(qiáng)功能和更加響應(yīng)式解決方案.
讓我們一起來看看:
根據(jù)我們的經(jīng)驗,Flux 經(jīng)常被過度使用,(就是大家總是在不需要它的時候仍然用了它).
Flux 提供了一種非常清晰的方式來存儲和更新App 全局 state(譯者注:對應(yīng) react 中的 state),并在需要的時候觸發(fā)渲染.
Flux 在管理App的全局狀態(tài)時很有用,比如:管理已登錄用戶狀態(tài),路由狀態(tài),或者是活躍賬號狀態(tài),但若是用來管理臨時數(shù)據(jù)或者本地數(shù)據(jù),立刻就會變得很痛苦.
我們不推薦使用 Flux 來管理路由相關(guān)的數(shù)據(jù),比如 /items/:itemId.獲取路由數(shù)據(jù)并存儲在組件的 state 之中.這種情況下,它會在組件銷毀時一起被銷毀.
如果你想了解更多關(guān)于 Flux 的信息,建議閱讀 The Evolution of Flux Frameworks.
Redux 是一個 JavaScript App的可預(yù)測 state 容器.
如果你覺得需要 Flux 或者相似的解決方案,你應(yīng)該了解一下 redux,并學(xué)習(xí) Dan Abramov 的 Getting started with redux,這能夠迅速提高你的開發(fā)技能.
Redux 延續(xù)并改進(jìn)了 Flux 的思想,學(xué)習(xí)了 Elm ,避開了 Flux 的復(fù)雜度(譯者注:Elm 是一門函數(shù)式編程語言).
1.扁平化 state
API 經(jīng)常會返回嵌套的資源.這在 Flux 或基于 Redux 的架構(gòu)中處理起來會非常困難.我們推薦使用 normalizr 這類庫將數(shù)據(jù)進(jìn)行扁平化處理,盡可能地扁平化state.
像這樣:
const data = normalize(response, arrayOf(schema.user)) state = _.merge(state, data.entities)
(我們使用isomorphic-fetch與API進(jìn)行通信)
2.使用 immutable state
共享的可變性 state 是罪惡的根源. - Pete Hunt, React.js Conf 2015
不可變對象是指在創(chuàng)建后不可再被修改的對象.
不可變對象可以讓我們免于痛苦,并且通過引用級的比對檢查來提升渲染性能.比如在 shouldComponentUpdate 中:
shouldComponentUpdate(nexProps) { // 不進(jìn)行對象的深度對比 return this.props.immutableFoo !== nexProps.immutableFoo }
3. 如何在JavaScript中實現(xiàn)不可變?
本辦法是小心的寫代碼,示例代碼如下,你需要在單元測試中通過 deep-freeze-node 來反復(fù)驗證.
return { ...state, foo } return arr1.concat(arr2)
相信我,這是最明顯的例子了.
更簡單也更自然的方式是使用 Immutable.js.
import { fromJS } from "immutable" const state = fromJS({ bar: "biz" }) const newState = foo.set("bar", "baz")
Immutable.js 非常之快,背后理念也非常美妙.哪怕你并不準(zhǔn)備使用它,我也推薦閱讀這個由 Lee Byron 所制作的視頻 Immutable Data and React.它非常深刻的講解了 Immutable.js 的工作原理.
4. Observables and Reactive 解決方案
如果你不喜歡 Flux/Redux 或者只是想要更加 reactive,不用失望!還有很多數(shù)據(jù)處理的方案供你選擇,這里有一個可能是你想要的庫的簡單列表:
cycle.js(“一個更清晰簡潔的函數(shù)式 reactive JavaScript 框架”)
rx-flux(“Flux 架構(gòu)與 Rxjs 的結(jié)合”)
redux-rx(“Redux的 Rxjs 工具集”)
mobservable(“可預(yù)測的數(shù)據(jù),reactive的功能,簡潔的代碼”)
路由幾乎所有 App 都有路由功能.如果你在瀏覽器中使用 React.js,你將會在挑選庫的時候遇到選擇性問題.
我們的選擇是react-router, 來自優(yōu)秀的 rackt 社區(qū).Racket 給 React.js 愛好者們帶來了很多高質(zhì)量資源.
要使用 react-router,請查看它的文檔.但更重要的是:如果你使用Flux/Redux,我們推薦你將路由 state 與 store 或全局 state 保持同步.
同步的路由 state 會幫助你控制 Flux/Redux Actions 的路由行為,并能在組件中讀取路由狀態(tài)和參數(shù).
Redux 用戶可以通過 redux-simple-router 這個庫輕松實現(xiàn)它.
只有一小部分 webpack 用戶知 App 代碼可以分割成多個 JavaScript 塊.
require.ensure([], () => { const Profile = require("./Profile.js") this.setState({ currentComponent: Profile }) })
這對于大型應(yīng)用十分有用,每次部署之后用戶瀏覽器不用下載那些很少會使用到的代碼,比如Profile頁面. 更多代碼塊將導(dǎo)致更多 HTTP 請求 - 但是使用 HTTP/2 多路復(fù)用就沒有問題.
結(jié)合 chunk hashing,可以在代碼更新之后優(yōu)化緩存命中率.
下個版本的 react-router 將會對代碼分隔做更多支持.
對于 react-router 的未來規(guī)劃,可以去查看博客 Ryan Florence: Welcome to Future of Web Application Delivery.
很多人都在抱怨JSX,但首先要知道,它在 React 中是可選的.
JSX 在最后都會通過 Babel 被編譯成 JavaScript.你可以直接編寫 JavaScript 來替代 JSX,但是在處理 HTML 的時候使用 JSX 會感覺更加自然.
特別是對于不懂技術(shù)的人來說,他們只可以理解和修改必要的部分.
JSX 是一種與 XML 類似的 JavaScript 語法擴(kuò)展.你可以通過一個簡單的 JSX 語法轉(zhuǎn)換器來轉(zhuǎn)換它.— JSX in depth
如果你想了解更多 JSX 的內(nèi)容,查看文章 JSX Looks Like An Abomination – But it’s Good for You
使用 ClassesReact 與 ES2015 的 Class 語法搭配的很好.
class HelloMessage extends React.Component { render() { return Hello {this.props.name} } }
相對于mixins,我們更喜歡高階組件,所以保留 createClass 更像是一個語法問題,而不是技術(shù)問題. 我們認(rèn)為使用 createClass 或者 React.Component 只是選擇不同而已,沒有對錯之分.
屬性類型如果你仍然沒有檢查 熟悉類型,那么你應(yīng)該從2016年開始做起,這將為你節(jié)省大量的時間,相信我.
MyComponent.propTypes = { isLoading: PropTypes.bool.isRequired, items: ImmutablePropTypes.listOf( ImmutablePropTypes.contains({ name: PropTypes.string.isRequired, }) ).isRequired }
當(dāng)然,也可以使用 react-immutable-proptypes 驗證 Immutable.js 所編寫的屬性.
高階組件當(dāng)前 mixins 將死,而且在 ES6 的 Class 不再支持 mixins,我們應(yīng)當(dāng)尋找新方案.
什么是高階組件?PassData({ foo: "bar" })(MyComponent)
簡單來講,從由原始組件創(chuàng)造一個新的組件并且擴(kuò)展它的行為.你可以在多種場景來使用它,比如鑒權(quán):requireAuth({ role: "admin" })(MyComponent)(檢查用戶權(quán)限,如果未登錄就跳轉(zhuǎn)),或者將組件與 Flux/Redux 的 store 連通.
在 RisingStack,我們也喜歡將數(shù)據(jù)拉取和控制類的邏輯分離到高階組件中,以盡可能地保持 view 層的簡單.
保證測試的高代碼覆蓋率是開發(fā)周期中的重要一環(huán).幸運的是,React.js 社區(qū)有很多這樣的庫來幫助我們.
組件測試AirBnb 的 enzyme 是我們最喜愛的組件測試庫之一.使用它的淺渲染特性可以對組件的邏輯和渲染結(jié)果進(jìn)行測試,非常神奇.它現(xiàn)在還不能替代selenium測試,但是將前端測試提升到了一個新高度.
it("simulates click events", () => { const onButtonClick = sinon.spy() const wrapper = shallow( ) wrapper.find("button").simulate("click") expect(onButtonClick.calledOnce).to.be.true })
看起來非常簡潔,不是嗎?
你使用 chai 作為測試斷言庫嘛?相信你會喜歡 chai-enyzime 的!
測試 reducer 非常簡單,它響應(yīng)新到來的 actions 然后將原來的 state 轉(zhuǎn)換為新的 state:
it("should set token", () => { const nextState = reducer(undefined, { type: USER_SET_TOKEN, token: "my-token" }) // immutable.js state output expect(nextState.toJS()).to.be.eql({ token: "my-token" }) })
測試 actions 也很簡單,但是異步 actions 就不太一樣了.對于測試異步的 actions 來說,我們推薦使用 redux-mock-store,非常有幫助.
it("should dispatch action", (done) => { const getState = {} const action = { type: "ADD_TODO" } const expectedActions = [action] const store = mockStore(getState, expectedActions, done) store.dispatch(action) })
關(guān)于更深入的 redux測試 ,請參考官方文檔.
使用 npm雖然 React.js 并不依賴代碼打包工具就可以工作得很好,但我們還是推薦使用 Webpack 或者 Browserify 來發(fā)揮 npm 的能力.Npm 有很多 React.js 的包,可以幫助你優(yōu)雅地管理依賴.
(請不要忘記復(fù)用你自己的組件,這是優(yōu)化代碼的絕佳方式.)
這本身不是一個 React 相關(guān)的問題,但是大多數(shù)人都在打包他們的 React 應(yīng)用,所以我有必要在這里提一下.
當(dāng)你打包源代碼的時候,要時刻警惕打包后文件的大小.想要將其控制在最小體積,你需要思考如何如何 require/import 依賴.
查看下面的代碼片段,這兩種方式可以對輸出大小會產(chǎn)生重大影響:
import { concat, sortBy, map, sample } from "lodash" // vs. import concat from "lodash/concat"; import sortBy from "lodash/sortBy"; import map from "lodash/map"; import sample from "lodash/sample";
查看Reduce Your bundle.js File Size By Doing This One Thing,以獲取更多信息.
我們也喜歡將代碼分離到至少 vendors.js 和 app.js 兩個文件,因為 vendors 相對于我們的代碼庫來說更新頻率低很多.
對輸出文件進(jìn)行 hash 命名(WebPack中的chunk hash),并使用長緩存,我們可以顯著地減少訪問用戶需要下載的代碼.結(jié)合代碼懶加載,優(yōu)化效果非常顯著.
如果你還不太熟悉 Webpack,可以查看這本優(yōu)秀的 React webpack cookbook.
如果你曾使用過hot reload編寫單頁面應(yīng)用,當(dāng)你在處理某些與狀態(tài)相關(guān)的事情時,可能你就會明白當(dāng)你在編輯器中點擊保存,整個頁面就重新加載了是多么令人討厭.你需要逐步點擊操作到剛才的環(huán)節(jié),然后在這樣的重復(fù)中奔潰.
通過 React,在重載組件的同時保持組件狀態(tài)已經(jīng)成為可能,從此不再痛苦!
關(guān)于如何搭建hot reload,可參考 react-transform-boilerplate.
前面有提到過,我們在 React.js 組件中使用 JSX,然后使用 Babel.js 進(jìn)行編譯.
Babel 的能力遠(yuǎn)不止這些,它也可以讓我們現(xiàn)在就可以給瀏覽器編寫 ES6/ES2015 代碼.在RisingStack,我們在服務(wù)器端和客戶端都使用了ES2015的特性,ES2015已經(jīng)可以在最新的LTS Node.js版本中使用了.
或許你已經(jīng)給你的 JavaScript 代碼制定了代碼規(guī)范,但是你知道也有用于 React 的代碼規(guī)范了嗎?我們建議你選擇一個代碼規(guī)范,然后照著它說的來做.
在 RisingStack,我們也將 linters 強(qiáng)制運行在 CI 系統(tǒng)上,git push 亦然.可以試試 pre-push 或者 pre-commit.
我們使用標(biāo)準(zhǔn)的 JavaScript 代碼風(fēng)格,并使用 eslint-plugin-react 來檢查React.js代碼.
(是的,我們已經(jīng)不再使用分號了)
相對而言 GraphQL 和 Relay 還屬于新技術(shù),在 RisingStack,我們還沒有在產(chǎn)品環(huán)境中使用它們,但保持關(guān)注.
我們寫過一個 Relay 的 MongoDB ORM 庫,叫做 graffiti,可以使用你已有的 mongoose models 來創(chuàng)建 GraphQL server.
如果你想要學(xué)習(xí)這些新技術(shù),我們建議你可以找來玩一玩.
有些優(yōu)秀的技術(shù)和庫其實跟React都幾乎沒關(guān)系,但要關(guān)注社區(qū)的其他人都在做些什么.2015這一年,React社區(qū)被 Elm 架構(gòu)啟發(fā)了很多.
如果你知道其它在2016年必要的 React.js 工具,請在下面給我們留言!
原文作者:Peter Marton,RisingStack技術(shù)總監(jiān)
原文鏈接:https://blog.risingstack.com/...
翻譯自力譜宿云LeapCloud團(tuán)隊_UX組成員:Jason關(guān)于MaxLeap
MaxLeap移動云服務(wù)平臺為企業(yè)提供一站式的移動研發(fā)和運營云服務(wù),幫助企業(yè)快速研發(fā)和上線移動應(yīng)用,平臺提供數(shù)據(jù)云存儲,云引擎,支付管理,IM,數(shù)據(jù)分析和營銷自動化等服務(wù)。
MaxLeap官網(wǎng)鏈接: https://maxleap.cn
歡迎關(guān)注微信公眾號:MaxLeap_yidongyanfa
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/79024.html
摘要:特意對前端學(xué)習(xí)資源做一個匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對前端學(xué)習(xí)資源做一個匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補充。有錯誤的地方,還請斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會及時更新,平時業(yè)務(wù)工作時也會不定期更...
摘要:一團(tuán)隊組織網(wǎng)站說明騰訊團(tuán)隊騰訊前端團(tuán)隊,代表作品,致力于前端技術(shù)的研究騰訊社交用戶體驗設(shè)計,簡稱,騰訊設(shè)計團(tuán)隊網(wǎng)站騰訊用戶研究與體驗設(shè)計部百度前端研發(fā)部出品淘寶前端團(tuán)隊用技術(shù)為體驗提供無限可能凹凸實驗室京東用戶體驗設(shè)計部出品奇舞團(tuán)奇虎旗下前 一、團(tuán)隊組織 網(wǎng)站 說明 騰訊 AlloyTeam 團(tuán)隊 騰訊Web前端團(tuán)隊,代表作品WebQQ,致力于前端技術(shù)的研究 ISUX 騰...
摘要:一團(tuán)隊組織網(wǎng)站說明騰訊團(tuán)隊騰訊前端團(tuán)隊,代表作品,致力于前端技術(shù)的研究騰訊社交用戶體驗設(shè)計,簡稱,騰訊設(shè)計團(tuán)隊網(wǎng)站騰訊用戶研究與體驗設(shè)計部百度前端研發(fā)部出品淘寶前端團(tuán)隊用技術(shù)為體驗提供無限可能凹凸實驗室京東用戶體驗設(shè)計部出品奇舞團(tuán)奇虎旗下前 一、團(tuán)隊組織 網(wǎng)站 說明 騰訊 AlloyTeam 團(tuán)隊 騰訊Web前端團(tuán)隊,代表作品WebQQ,致力于前端技術(shù)的研究 ISUX 騰...
摘要:一團(tuán)隊組織網(wǎng)站說明騰訊團(tuán)隊騰訊前端團(tuán)隊,代表作品,致力于前端技術(shù)的研究騰訊社交用戶體驗設(shè)計,簡稱,騰訊設(shè)計團(tuán)隊網(wǎng)站騰訊用戶研究與體驗設(shè)計部百度前端研發(fā)部出品淘寶前端團(tuán)隊用技術(shù)為體驗提供無限可能凹凸實驗室京東用戶體驗設(shè)計部出品奇舞團(tuán)奇虎旗下前 一、團(tuán)隊組織 網(wǎng)站 說明 騰訊 AlloyTeam 團(tuán)隊 騰訊Web前端團(tuán)隊,代表作品WebQQ,致力于前端技術(shù)的研究 ISUX 騰...
摘要:前戲補上參會的完整記錄,這個問題從一開始我就是準(zhǔn)備自問自答的,希望可以通過這種形式把大會的干貨分享給更多人。 showImg(http://7xqy7v.com1.z0.glb.clouddn.com/colorful/blog/feday2.png); 前戲 2016/3/21 補上參會的完整記錄,這個問題從一開始我就是準(zhǔn)備自問自答的,希望可以通過這種形式把大會的干貨分享給更多人。 ...
閱讀 1238·2021-11-11 16:55
閱讀 1537·2021-10-08 10:16
閱讀 1188·2021-09-26 10:20
閱讀 3569·2021-09-01 10:47
閱讀 2450·2019-08-30 15:52
閱讀 2681·2019-08-30 13:18
閱讀 3193·2019-08-30 13:15
閱讀 1114·2019-08-30 10:55