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