摘要:你是一個(gè)對感興趣的開發(fā)者嗎不用擔(dān)心,這真的不會(huì)讓你成為一個(gè)背叛者或其他什么,真的。事實(shí)上,這個(gè)想法并不是或獨(dú)創(chuàng)的它只是一種很棒的軟件開發(fā)實(shí)踐方式。把代碼分離到不同的文件里并不會(huì)自動(dòng)導(dǎo)致關(guān)注點(diǎn)分離。
原文鏈接 : Getting to Grips with React (as an Angular developer)
原文作者 : DAVE CEDDIA
譯者 : 李林璞(web前端領(lǐng)域)
譯者注:翻譯如有疏漏,歡迎指出!感謝!轉(zhuǎn)載請保留此頭部。
你是一個(gè)對 React 感興趣的 Angular 開發(fā)者嗎?不用擔(dān)心,這真的不會(huì)讓你成為一個(gè)背叛者或其他什么,真的。
或許你早就已經(jīng)開始玩 React 了:閱讀了 Facebook 的官方教程,創(chuàng)建了一些組件...
也或許你正處于我?guī)讉€(gè)月前處于的境地:對React完全沒有經(jīng)驗(yàn),除了聽說過它有多快,它有個(gè)虛擬 DOM 的概念,單向綁定,和一些像 Flux , Redux 和 Reflux 之類亂七八糟的東西。
在接下來一系列的文章里我將嘗試幫助你將你辛苦習(xí)來的 “Angular” 主義知識應(yīng)用到 React 當(dāng)中。
在 Angular 里,你可能已經(jīng)習(xí)慣去編寫各種指令 directive。如果你是按照流行的規(guī)范去編碼的話,相信你程序的各個(gè)部分都是由一個(gè)或多個(gè)指令構(gòu)建而成,并到處都使用了隔離的作用域 scope(如果這聽起來很熟悉但并不像你所做的話,或許你可以閱讀一下將scope轉(zhuǎn)化為controllerAs)。
React 有著相同的概念:編寫組件 component。將你的程序按功能拆分成組件塊,并盡可能讓每個(gè)組件塊保持獨(dú)立和可復(fù)用性。事實(shí)上,這個(gè)想法并不是 React 或 Angular 獨(dú)創(chuàng)的 - 它只是一種很棒的軟件開發(fā)實(shí)踐方式。盡可能寫一些簡短并具備可復(fù)用性的代碼(函數(shù),組件,指令,隨便你怎么稱呼它們)。
一個(gè)關(guān)鍵的差別在于 React 里 所有東西都是組件 ,從根節(jié)點(diǎn)到下面所有。Angular 讓你使用 ng-controller 去混合和匹配所有指令,并在之后特定地路由出各自的指令和模板... React 讓這個(gè)事情變簡單了一點(diǎn)。所有東西都是組件,頁面,按鈕甚至是路由,我們隨后會(huì)講到這些。
好了,所以說 React 的“組件”是類似于“指令”的。那么它的代碼看起來是怎樣的呢?
下面是一個(gè)展示歌曲名字的 Angular 指令:
angular.module("demo", []).directive("songName", function() {
return {
scope: {
song: "="
},
restrict: "E",
template: "{{ ctrl.song.name }}",
controller: function() {},
controllerAs: "ctrl",
bindToController: true
};
});
接下來是用 React 寫的相同功能的組件:
var SongName = React.createClass({
propTypes: {
song: React.PropTypes.object.isRequired
},
render: function() {
return {this.props.song.name};
}
});
你馬上就可以發(fā)現(xiàn)一些相似之處:它們都期望得到一個(gè) song 對象,并都似乎有各種各樣的模板。
一些不同之處在于:React 相對 Angular 有著更少的代碼。我敢說...更簡潔了不是嗎?React 里,期望的參數(shù)(song)有著某種類型驗(yàn)證,并且 HTML 沒有引號!
事實(shí)上那個(gè)看上去沒加引號的 HTML 并不是真正的 HTML。(等下就會(huì)講到)
React.createClass 和 angular.directive 類似 - 它創(chuàng)建了一個(gè)組件類。這個(gè)組件 必須 有一個(gè) render 方法,propTypes 是一個(gè)可選對象,但最好把它寫上。
還是要對得起 Angular ,它的1.5版本其實(shí)介紹了一個(gè) component 方法來縮短指令的長度,所以上面的指令可以簡寫成下面這樣:
angular.module("demo", []).component("songName", {
bindings: {
song: "="
},
template: "{{ $ctrl.song.name }}"
});
更簡單的寫法。它甚至默認(rèn)沒有控制器!我推薦閱讀一下Todd Motto的關(guān)于組件方法的文章并在你的代碼里嘗試一下。
但它還是沒有 propTypes ...
propTypespropTypes是一個(gè)驗(yàn)證組件所需參數(shù)的方法。你可以把個(gè)別參數(shù)標(biāo)記為“必需的”或“可選的”(默認(rèn)它們都是可選的),把它想象成類型檢測吧。
下面是真正很酷的部分:如果你指定了propTypes并說明一個(gè)參數(shù)是必需的(像上面那樣),然后你忘記把它傳進(jìn)來,你就會(huì)在控制臺(tái)得到一個(gè)提示信息。
比起 Angular 這真的太棒了!當(dāng)你忘記給指令傳參時(shí)你就再也不怕莫名其妙地報(bào)錯(cuò)了。
props什么是 "prop" ?它實(shí)際上是 “property” 的簡寫(感謝 React 的開發(fā)者,讓我們再也不用打出 this.properties 或者 this.propertyTypes 了)。
你可以把 props 看作是傳給組件的屬性。就像在指令里,你會(huì)在 HTML 元素里傳遞屬性一樣 - props 會(huì)在 JSX 元素里被當(dāng)作屬性傳遞。
使用組件下面是 Angular 里指令的使用方法:
// Notice how you have to mentally translate "songName" to "song-name"?
然后下面是 React 里組件的使用方法:
// Notice how you DON"T need to mentally translate SongName to anything?
所有沒有子元素的標(biāo)簽在 JSX 里都可以自終止。
但讓我們先花幾分鐘來講講 JSX吧...
JS里的HTML?!在我對 React 了解不多的時(shí)候,我知道它是把 HTML 和 JS 混合起來的,然后我就想這樣做真的很 丑陋 啊。我意思是,這對于最佳實(shí)踐的思考來說已經(jīng)很多年不會(huì)這么寫了不是嗎?從那段使用 jQuery 的黑暗日子開始,我們就已經(jīng)知道在 JS 里寫 HTML 元素是一件很取巧而且開發(fā)體驗(yàn)相當(dāng)糟糕的事情,所以為什么 React 會(huì)再次犯同樣的錯(cuò)誤呢?
所以,這里有兩件事情需要搞清楚:
那并不是字符串。
你注意到它是怎么做到不給 “HTML” 加引號的嗎?那是因?yàn)樗⒉皇?HTML。不加引號也并不是一種語法糖,React 是不會(huì)將那個(gè)東西轉(zhuǎn)換成 HTML 的。
那并不是HTML。
那是 JSX 。我知道它長得很像 HTML ,馬上你可能會(huì)想:“JSX嘛 ...只是對 HTML 做了一些細(xì)微的改變?nèi)缓髶Q了個(gè)名字而已”,好吧,你也可以那么說。我倒覺得它是給我們提供了一種用函數(shù)調(diào)用去創(chuàng)建 DOM 元素的語法糖。
創(chuàng)建 DOM 元素的函數(shù)調(diào)用?是的,看看下面的代碼:
// This JSX...
{this.props.song.name}
// Compiles to this function call:
React.createElement("span", {className: "song-name"}, this.props.song.name);
// React.createElement("tagName", props, children);
看起來還挺有道理的,不是嗎? HTML 創(chuàng)建嵌套的 DOM 節(jié)點(diǎn),那我們就用嵌套的函數(shù)調(diào)用替代了嵌套的 DOM 節(jié)點(diǎn)...
// This is valid JSX:Hello World// ...which compiles to this call: React.createElement("div", null, React.createElement("span", {className: "greeting"}, React.createElement("strong", null, "Hello"), React.createElement("strong", null, "World") ));
實(shí)現(xiàn)上來說,這些 React.createElement 方法并沒有創(chuàng)建真正的 DOM 節(jié)點(diǎn),它們創(chuàng)建了虛擬的 DOM 節(jié)點(diǎn)。
但...關(guān)注點(diǎn)的分離!所以說我們并不是把 HTML 字符串寫到 Javascript 里的!
但代碼邏輯始終還是和表現(xiàn)層混合起來的!那可不能算對!這么多年的軟件開發(fā)實(shí)踐告訴我們這樣做是很不好的。放心,現(xiàn)在只是還沒做完呢,你并沒有把視圖和邏輯混合起來。
我認(rèn)為這是一種類似“貨物崇拜”的東西,我們經(jīng)常在沒真正搞清楚為什么的情況下去贊同和執(zhí)行。有很多很好的理由去說明為什么需要把邏輯和視圖層給分離開,但當(dāng)你回頭再看會(huì)發(fā)現(xiàn)同樣也有很多很好的理由去合并它們。
或許你已經(jīng)寫過一些帶有控制器和分離的模板文件的 Angular 指令了是吧?
告訴我你有多么經(jīng)常在看不到或者無法修改控制器的情況下去到模板文件里去修改一些東西?又有多么經(jīng)常在沒有接觸到模板的情況下去修改控制器?
這些看上去算是你對關(guān)注點(diǎn)的分離嗎?
我們喜歡把 JS 和 HTML 分離到不同的文件里去讓它們“關(guān)注點(diǎn)分離”,可復(fù)用性我們來了!
但其實(shí)它們很少會(huì)那樣工作。一個(gè)指令的控制器和模板通常會(huì)緊緊關(guān)聯(lián)在一起,所以很自然地,它們就像是硬幣的兩面。把代碼分離到不同的文件里并不會(huì)自動(dòng)導(dǎo)致關(guān)注點(diǎn)分離。
如果你還沒注意到的話,其實(shí)我是想嘗試通過上面的說法告訴你模板和邏輯控制其實(shí)是可以共存在一個(gè)文件里的,而且這樣做或許看起來更有道理一些。
試試看我敢打賭你還是充滿疑惑。正常,我曾經(jīng)也是的。
個(gè)人來說,我發(fā)現(xiàn)從長期以來信服的理論當(dāng)中跳出來到一個(gè)看似完全相反的位置確實(shí)是一件相當(dāng)困難的事情。我試過親自去嘗試那么做并證明給自己看這個(gè)新方法并不是那么糟糕。
希望你也可以去做同樣的事情,只需要一點(diǎn)點(diǎn)時(shí)間。去嘗試一下 React 的官方教程(不需要什么亂七八糟的工具 - 下載并運(yùn)行他們的服務(wù)就可以開始寫代碼了),或者也可以試一下我的三分鐘輸出 Hello World 教程(不需要編譯哦?。?。
或許就可以像我做的那樣,你會(huì)發(fā)現(xiàn)寫 React 組件確實(shí)很有意思。又或者你會(huì)發(fā)現(xiàn) React 并不是你想要的東西,但至少你嘗試并驗(yàn)證過了。
如果你決定使用它了,那就回來這兒吧,我等你!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/87804.html
摘要:正在暑假中的課多周刊第期我們的微信公眾號,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。若有幫助,請把課多周刊推薦給你的朋友,你的支持是我們最大的動(dòng)力。原理微信熱更新方案漲知識了,熱更新是以后的標(biāo)配。 正在暑假中的《課多周刊》(第1期) 我們的微信公眾號:fed-talk,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。 若有幫助,請把 課多周刊 推薦給你的朋友,你的支持是我們最大的動(dòng)力。 遠(yuǎn)上寒山石徑...
摘要:正在暑假中的課多周刊第期我們的微信公眾號,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。若有幫助,請把課多周刊推薦給你的朋友,你的支持是我們最大的動(dòng)力。原理微信熱更新方案漲知識了,熱更新是以后的標(biāo)配。 正在暑假中的《課多周刊》(第1期) 我們的微信公眾號:fed-talk,更多精彩內(nèi)容皆在微信公眾號,歡迎關(guān)注。 若有幫助,請把 課多周刊 推薦給你的朋友,你的支持是我們最大的動(dòng)力。 遠(yuǎn)上寒山石徑...
摘要:在其他方面,我們只需要考慮針對特定任務(wù)時(shí)所使用框架的成本。當(dāng)我們必須使用或不應(yīng)該使用框架時(shí)我強(qiáng)烈主張要了解編寫某個(gè)工具的目的。 非常有價(jià)值的建議:哪些框架是合理的,哪些并不合理。 作者:Tod Hansmann 來源:https://opensource.com/articl...翻譯:瘋狂的技術(shù)宅說明:本專欄文章首發(fā)于公眾號:jingchengyideng 。 showImg(htt...
摘要:掘金日報(bào)第四期使用怎么能不知道這些插件合集掘金日報(bào)主打分享優(yōu)質(zhì)深度技術(shù)內(nèi)容,技術(shù)內(nèi)容分前端后端產(chǎn)品設(shè)計(jì)工具資源和一些有趣的東西。目前已經(jīng)涵蓋了的相關(guān)資源鏈接,供大家參考與學(xué)習(xí)。 【掘金日報(bào)】第四期 使用Sublime?怎么能不知道這些 Sublime 插件合集! 掘金日報(bào)主打分享優(yōu)質(zhì)深度技術(shù)內(nèi)容,技術(shù)內(nèi)容分:前端、后端、Android、iOS、產(chǎn)品設(shè)計(jì)、工具資源和一些有趣的東西。 前端...
摘要:掘金日報(bào)第四期使用怎么能不知道這些插件合集掘金日報(bào)主打分享優(yōu)質(zhì)深度技術(shù)內(nèi)容,技術(shù)內(nèi)容分前端后端產(chǎn)品設(shè)計(jì)工具資源和一些有趣的東西。目前已經(jīng)涵蓋了的相關(guān)資源鏈接,供大家參考與學(xué)習(xí)。 【掘金日報(bào)】第四期 使用Sublime?怎么能不知道這些 Sublime 插件合集! 掘金日報(bào)主打分享優(yōu)質(zhì)深度技術(shù)內(nèi)容,技術(shù)內(nèi)容分:前端、后端、Android、iOS、產(chǎn)品設(shè)計(jì)、工具資源和一些有趣的東西。 前端...
閱讀 1879·2021-11-15 11:39
閱讀 1244·2021-10-18 13:29
閱讀 1201·2021-08-31 09:42
閱讀 2753·2019-08-30 11:11
閱讀 2130·2019-08-26 12:12
閱讀 2121·2019-08-26 10:17
閱讀 3398·2019-08-23 18:38
閱讀 3236·2019-08-23 18:38