摘要:由于其名氣和穩(wěn)定性獲得了廣泛好評。但是實際上在中并不是非常必要的。因此,這些結果也是純粹的速度實驗。它是否容易使用,開發(fā)過程是否令人愉快年和年的狀態(tài)報告顯示,和都享有良好的聲譽,大多數(shù)開發(fā)人員表示會再次使用。上手最簡單和最快的學習曲線。
翻譯:瘋狂的技術宅
原文:https://www.toptal.com/react/...
本文首發(fā)微信公眾號:jingchengyideng
歡迎關注,每天都給你推送新鮮的前端技術文章
前端和 JavaScript 是一個奇怪的世界。大量不斷推出的新技術的同時,也在被不需要它們的人嘲笑,往往很多人都會這樣做。我們有時會對不斷涌現(xiàn)的信息、庫和討論感到不知所措,總希望能有一些穩(wěn)定的東西,就像能讓我們可以休整一段時間的避風港。最近 React 似乎有變成 JavaScript 演變海洋中溫暖港灣的趨勢。
正是考慮到這一點,我們決定制作這個 React 系列教程,展示它的功能,并看看它與 Angular 和 VueJS 相比有什么特點。
當然 React 并不是唯一的選擇,但目前它是最受歡迎、最穩(wěn)定、最具有創(chuàng)新性的解決方案之一,雖然它仍然在不斷升級,但更多的是在改進,而不是增加功能。
2019年的 ReactReact 是一個視圖庫,可以一直追溯到2011年,當時它的第一個原型名為 FaxJs,并出現(xiàn)在 Facebook 上,React 是由 Jordan Walke(他也是上述原型的作者)于2013年5月29日在 JSConfUS 推出的,并于2013年7月2日在 GitHub 上公開發(fā)布。
在2014年,當開始擴大社區(qū)并推廣 React 時,它受到持續(xù)歡迎。然而從我的角度來看,2015年是大型公司(例如 Airbnb 和 Netflix )開始喜歡并采用 React 的里程碑年。此外,當年還出現(xiàn)了React Native。 React Native背后的想法并不是什么全新的東西,不過看起來很有趣,尤其是因為它得到了 Facebook 的支持。
另一個重大變化是 Redux,一個 Flux 實現(xiàn)。這使狀態(tài)管理方式更加簡單友好,使其成為迄今為止最成功的實現(xiàn)。
從其出現(xiàn)一直到現(xiàn)在,還有很多其他的東西供我們使用,包括 React tools,重寫了核心算法;Fiber 用于語義轉換版本控制等等。到了今天,我們處于 v16.6.3,幾周后可能就會發(fā)布支持 Hooks 的新版本(它應該在 16.7.0 得到支持,但由于對 React.lazy 做了一些修復,就先發(fā)布了一個版本)。React 由于其名氣和穩(wěn)定性獲得了廣泛好評。
但 React 到底是什么?好吧,如果你身為前端開發(fā)人員但是從來都沒有聽說過,那么我就要說聲“恭喜你”,因為這是一個了不起的壯舉。
開個玩笑而已。React 是一個聲明式的基于組件的視圖庫,可以幫助你構建 UI。它是一個庫而不是一個框架,雖然最初很多人把它描述為后者。
顯然,如果我們要把 Redux 和 React Router 等添加到 React,它就擁有了制作常規(guī)單頁應用程序所需的所有東西,這可能這就是它有時被錯誤地描述為框架而不是庫的原因 。如果一定要這樣認為的話,將該環(huán)境的所有組件放在一起,術語“框架”可能有點適合它,但就其本身而言,React 僅僅是一個庫。
不要再糾結改怎么對其分類了,先關注 React 有什么獨特之處,一些之前沒有注意到的東西。首先,當你第一次看到 React 時,就會想到 JSX,因為這是你看到代碼時的第一個感受。 JSX是一種 JavaScript 語法擴展,有點類似于 HTML/XML。說到 React 和 JSX,它們與 HTML 有一些區(qū)別,例如,React 中的類是 className,沒有tabindex 但是有 tabIndex,樣式接受具有駝峰命名的屬性的 JavaScript 對象,依此類推。
有一些細微的差別,但是任何人都應該立即接受它們。事件處理是通過例如 onChange 和 onClick 屬性實現(xiàn)的,這些屬性可以用來附加一些函數(shù)來處理事件。此外,以后的組件可以通過使用 props 自由重用和自定義,因此沒有理由多次編寫相同的代碼。
import React, { Component } from "react"; export default class App extends Component { render() { return (Hello World, {this.props.name}); } }
但是實際上 JSX 在 React 中并不是非常必要的。你可以編寫常規(guī)函數(shù)來創(chuàng)建元素,而無需使用JSX。上面的代碼可以像下面這樣去用。
import React, { Component } from "react"; export default class App extends Component { render() { return React.createElement( "div", null, "Hello World, ", this.props.name ); } }
很顯然我并不是建議你用這樣的語法,盡管有些情況下它有可能會派上用場(例如你想要引入一個非常小的東西但是又不想更改構建環(huán)境)。
實際上我展示上述代碼還有另一個原因。通常,開發(fā)人員不理解我們?yōu)槭裁葱枰獔?zhí)行以下操作:
import React from "react";
代碼片段應該是能夠自解釋的。即使我們正在提取 Component,仍然需要 React,因為 Babel 在 JSX 之上轉換為 React.createElement。所以如果我們不導入 React 就會失效。前面我提到了 Babel,這是一個工具,可以幫助我們預覽那些尚未在 JavaScript 中(更確切地說是在瀏覽器中)支持的東西,或者以某種方式對 JavaScript 進行擴展(或者類似于 TypeScript,Babel 從 Babel 7 開始支持的不同語言)。感謝Babel:
JSX 將被轉化為成瀏覽器可以理解的代碼。
我們可以使用尚未在瀏覽器中實現(xiàn)的新功能(例如類屬性)。
我們可以支持新瀏覽器中的特性,同時在舊瀏覽器中支持較舊的功能。
簡而言之,在 JavaScript 中,就是今天的代碼明天仍然能用;這可能需要為此專門再寫一篇文章。值得一提的是,React 的導入也可以被一些其他技術繞過(比如通過 Webpack 引入 ProvidePlugin 等),但是由于篇幅有限,我們將避免使用這種方式,并假設用戶將使用 Create React App( CRA)(稍后將提到有關此工具的更多信息)。
另一點比 JSX 本身更重要,那就是 React 基于虛擬 DOM。簡而言之,虛擬 DOM 是用 JavaScript 編寫的在內(nèi)存中的理想樹結構,稍后我們會把它與真實 DOM 進行比較。
怎樣與 Angular 和 Vue 進行比較?我很不喜歡對庫進行比較,特別是當我們被迫把梨和蘋果放在一起進行比較時。
因此,我將嘗試使用一系列簡短的問題和答案將 React 與 Angular 和 Vue 進行比較。這種比較與技術相關,而不是主觀的作出 “X比Y更好,因為它使用 JSX 而不是模板。” 這種出于個人偏好的對比。另外在速度和內(nèi)存分配等方面 React 與其主要競爭對手(Angular 和 Vue 都能想得到)非常相似,有一篇關于這個問題的文章很不錯,但請記住這一點:絕大多數(shù)程序并不會做這種處理上萬行數(shù)據(jù)的事。因此,這些結果也是純粹的速度實驗。實際上你也不會把這放在首位。
那么讓我們來看看關于 React 的問題以及它與競爭對手的比較:
我想擁有更多的工作機會。 React 到底有多受歡迎?
嗯,這很容易回答 —— 選擇 React。實際上,我會說 React 的工作機會大約其它的 6 到 10 倍(可能出入比較大,在一些大網(wǎng)站是 50 倍,也有些網(wǎng)站是 6 倍),是 Vue 的 2 到 4倍,比 Angular 更多。對 React experts 的需求很大,但是為什么 Vue 在 GitHub 上非常受歡迎(實際上它獲得了比 React 更多的star)卻沒有更多的職位空缺?這點我不知道。【譯者注:作者是美國人,這里指的是美國的就業(yè)市場】
我想要一個很大的社區(qū),還有大量的庫,能夠快速解決可能出現(xiàn)的問題。
選 React,不要再猶豫了。
它是否容易使用,開發(fā)過程是否令人愉快?
2018年和2017年的 JS 狀態(tài)報告顯示,React 和 Vue 都享有良好的聲譽,大多數(shù)開發(fā)人員表示會再次使用。另一方面Angular 有一種趨勢,每年都會有越來越多的人說不會再次使用它。
我想創(chuàng)建一個新的單面應用,但我不想額外去找這種支持庫。
我認為這大概是 Angular 值得選擇的唯一原因。
我不是大公司。但是希望盡可能獨立,應該選擇哪個?
Vue —— 它是我們?nèi)揞^中唯一獨立的一個。 ( Facebook 支持 React,而 Google 支持 Angular。)
上手最簡單和最快的學習曲線?
Vue/React。在這里我更傾向于 Vue,但這只是我個人的意見。至于為什么?因為你不需要懂 JSX(它是可選的),它基本上只是 HTML + CSS + JavaScript。
React Tutorial:開始你的第一個程序目前上手 React 最簡單方法是使用 CRA,這是一個為你創(chuàng)建項目的 CLI 工具,可幫助你避免配置 Webpack / Babel 等環(huán)境。你只需要依賴默的認配置方式,并隨著時間的推移更新包含在內(nèi)的內(nèi)容。多虧了這一點,你無需關心某些關鍵庫的主要更新。
當然,稍后,你可以通過運行 npm run eject 來“彈出”自己并自己處理每個細節(jié)。這種方法有其自身的優(yōu)點,因為你可以增加原來不可用的東西(例如裝飾器)來增強你的應用,但它也可能是令人頭疼的問題,因為它需要花費更多的時間去配置許多額外的文件。
所以,首先要做的是:
npx create-react-app {app-name}
然后 npm run start 就完成了。
類組件與函數(shù)組件我們應該先解釋這些組件的不同之處。基本上每個組件可以是 function 或 class。它們之間的主要區(qū)別在于,類組件有函數(shù)組件中沒有的一些功能:它們有 state 并使用 refs、生命周期等。從 v16.7 開始我們可以使用 hooks,因此可以使用 hooks 來進行 state 和 refs。
類組件有兩種類型:Component 和 PureComponent。它們唯一的區(qū)別是 PureComponent 可以對 props 和 state 進行淺層比較 —— 這在你不想“浪費”渲染資源的情況下有獨到的好處,一個組件及其子組件恰好在渲染后處于相同狀態(tài)。不過它只有一個淺層比較;如果你想實現(xiàn)自己的比較操作(假如你傳遞的是復雜的 props),只需要用 Component 并覆蓋 shouldComponentUpdate(默認情況下返回true)。從 16.6 + 開始,在函數(shù)組件中也可以用類似的東西 —— 全靠 React.memo 這個更高階的組件,在默認情況下表現(xiàn)得像 PureComponent(淺層比較),在你進行自定義的 props 比較時它還需要第二個參數(shù)。
一般來說如果你能用函數(shù)組件(假設你不需要類功能)那么就用它。不過從 16.7.0 開始,由于生命周期方法,只能用類組件。但是我認為函數(shù)組件更透明,更容易推理和理解。
React 生命周期方法Constructor(props)
可選,CRA 使其變得受歡迎,默認包含 JavaScript 的類字段聲明。聲明是否通過類中的箭頭函數(shù)去綁定方法是沒有意義的。類似的狀態(tài)也可以初始化為類屬性。
僅用于 ES6 類中初始化對象的本地狀態(tài)和綁定方法。
componentDidMount()
在這里進行 Ajax 調(diào)用。
如果你需要事件監(jiān)聽器,訂閱等功能,可以在此處添加。
你可以在這里使用 setState(但是它會使組件重新渲染)。
componentWillUnmount()
清除所有仍在進行的東西 —— 例如,Ajax應該被中斷,取消訂閱,清除定時器等等。
不要調(diào)用 setState,因為它沒有意義,因為組件將會被卸載(并且你會得到一個警告)。
componentDidUpdate(prevProps, prevState, snapshot)
在組件剛剛更新完畢時執(zhí)行(在開始渲染時不會)。
有三個可選的參數(shù)(以前的props,以前的 state 和只有在你的組件實現(xiàn) getSnapshotBeforeUpdate 時才會出現(xiàn)的快照 )。
僅當 shouldComponentUpdate 返回true時才會執(zhí)行。
If you use setState here, you should guard it or you will land in an infinite loop.
如果你在這里用到了 setState,應該保護它,否則將會陷入無限循環(huán)。
shouldComponentUpdate(nextProps, nextState)
僅用于性能優(yōu)化。
如果返回 false,則不會調(diào)用渲染器。
如果重寫的 SCO 只是對 props/state的淺層比較,可以使用 PureComponent。
getSnapshotBeforeUpdate()
可用于保存一些與當前 DOM 有關的信息,例如當前的滾動位置,稍后可在 componentDidUpdate 中重用,用來恢復滾動的位置。
componentDidCatch(error, info)
應該記錄日志錯誤的地方。
可以調(diào)用 setState,但在以后的版本中,將會在靜態(tài)方法getDerivedStateFromError(error) 中被刪除,它將通過返回一個值來更新狀態(tài)。
還有兩種靜態(tài)方法,在其他的段落中提到過
static getDerivedStateFromError(error)
此處提供錯誤信息。
應返回一個對象值,該值將會更新可用于處理錯誤的狀態(tài)(通過顯示內(nèi)容)。
由于它是靜態(tài)的,因此無法訪問組件實例本身。
static getSnapshotBeforeUpdate(props, state)
應該在 props 隨時間變化的情況下使用 —— 例如根據(jù) React docs,它可能用于轉換組件。
由于它是靜態(tài)的,因此無法訪問組件實例本身。
注意,目前還有更多可用的方法,但它們可能會在 React 17.0 中被刪除,所以就不在這里沒有提起了。
State vs. Props我們先從 Props 開始,因為它更容易解釋。Props 是傳給組件的屬性,以后可以在組件顯示信息或業(yè)務邏輯時重用它 。
import React, { Component } from "react"; export default class App extends Component { render() { return (); } } const HelloWorld = (props) => Hello {props.name}
在上面的例子中,name 是一個 prop。prop 是只讀元素,不能直接在子組件中更改。很多人有一種不太好的習慣,那就是把 prop 復制到 state ,然后再對 state 進行操作。當然有時候你希望執(zhí)行類似 “在提交之后去更新父組件的初始狀態(tài)” 這樣的操作,但這種情況非常少見 —— 在這種情況下,更新初始狀態(tài)可能有意義。另外不僅可以給子組件傳遞字符串這樣的 prop ,還可以傳遞數(shù)字、對象、函數(shù)等。
prop 還有一個更有用的東西叫做 defaultProps,這是一個靜態(tài)字段,它可以告訴你組件的默認 prop 是什么(比如當它們沒有傳遞給組件時)。
在“狀態(tài)提升”的情況下,其中一個組件(父組件)具有稍后由其子組件重用的狀態(tài)(例如,一個子組件用來顯示而另一個用來編輯),那么我們需要將該功能從父組件傳遞給子組件。 它允許我們更新父級的本地狀態(tài)。
另一方面,狀態(tài)是一個可以修改的本地狀態(tài),但是通過 this.setState 間接修改。如果直接去改變狀態(tài),組件將不會感知到,更不會因為狀態(tài)的改變而重新渲染。
SetState 是一種更改本地狀態(tài)對象的方法(通過執(zhí)行淺層合并),之后組件通過重新渲染自己來響應它。請注意,在使用 setState 之后,this.state 屬性不會立即對更改(它具有異步性質(zhì))作出反應,因為優(yōu)化的原因,可能會將 setState 的幾個實例一起進行批處理。調(diào)用它的方式有好幾種,其中一種方式允許我們在對狀態(tài)進行更新能夠后立即對組件執(zhí)行某些操作:
setState({value: ‘5’})
setState((state, props) => ({value: state.name + “‘s”}))
setState([object / function like above], () => {}) —— 這個表單允許我們附加 callback,當 state 顯示我們想要的數(shù)據(jù)時被調(diào)用(在第一個參數(shù))。
import React, { Component } from "react"; export default class App extends Component { state = { name: "Someone :)" } onClick = () => this.setState({ name: "You" }) render() { return (React Context); } } const HelloWorld = (props) => Hello {props.name}
React 最近穩(wěn)定的 Context API(已經(jīng)在 React 中存在了相當長的時間,盡管被 Redux 等一些最受歡迎的庫廣泛使用,卻是一個實驗性功能)有助于我們解決一個問題:Props drilling。簡而言之 Props drilling 是在結構中深入傳遞 props 的一種方式 —— 例如,它可以是組件的某種主題、針對特定語言的本地化、用戶信息等。在 Context出現(xiàn)之前(或者更確切地說,在它變成非實驗功能之前),它是通過遞歸方式從父級一直傳遞到到子級的最后一級的來進行鉆取的(顯然還有可以解決這個問題的 Redux)。請注意,此功能僅僅用于解決 Props drilling 的問題,并且不能替代 Redux 或 Mobx 等。當然如果你只使用狀態(tài)管理庫,則可以隨意替把它替換掉。
總結這是我們的React教程的第一部分。在后續(xù)的文章中,我們會設計更多高級主題,包括樣式和類型檢查,以及生產(chǎn)部署和性能優(yōu)化。
歡迎繼續(xù)閱讀本專欄其它高贊文章:12個令人驚嘆的CSS實驗項目
世界頂級公司的前端面試都問些什么
CSS Flexbox 可視化手冊
過節(jié)很無聊?還是用 JavaScript 寫一個腦力小游戲吧!
從設計者的角度看 React
CSS粘性定位是怎樣工作的
一步步教你用HTML5 SVG實現(xiàn)動畫效果
程序員30歲前月薪達不到30K,該何去何從
第三方CSS安全嗎?
談談super(props) 的重要性
本文首發(fā)微信公眾號:jingchengyideng 歡迎掃描二維碼關注公眾號,每天都給你推送新鮮的前端技術文章文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102179.html
摘要:個人所有文章同步到前言最近公司準備開發(fā)幾款可以在微信小程序端和端同時運行的一套商城,接著就是任務下發(fā)嘍,但是有一點,時間緊任務重,直接說其他的不管,反正幾個星期之內(nèi)必須上線,頭疼。 個人所有文章同步到:https://github.com/zhengzhuan... 前言 最近公司Boss準備開發(fā)幾款可以在微信小程序端和H5端同時運行的一套商城,接著就是任務下發(fā)嘍,但是有一點,時間緊任...
摘要:一團隊組織網(wǎng)站說明騰訊團隊騰訊前端團隊,代表作品,致力于前端技術的研究騰訊社交用戶體驗設計,簡稱,騰訊設計團隊網(wǎng)站騰訊用戶研究與體驗設計部百度前端研發(fā)部出品淘寶前端團隊用技術為體驗提供無限可能凹凸實驗室京東用戶體驗設計部出品奇舞團奇虎旗下前 一、團隊組織 網(wǎng)站 說明 騰訊 AlloyTeam 團隊 騰訊Web前端團隊,代表作品WebQQ,致力于前端技術的研究 ISUX 騰...
摘要:一團隊組織網(wǎng)站說明騰訊團隊騰訊前端團隊,代表作品,致力于前端技術的研究騰訊社交用戶體驗設計,簡稱,騰訊設計團隊網(wǎng)站騰訊用戶研究與體驗設計部百度前端研發(fā)部出品淘寶前端團隊用技術為體驗提供無限可能凹凸實驗室京東用戶體驗設計部出品奇舞團奇虎旗下前 一、團隊組織 網(wǎng)站 說明 騰訊 AlloyTeam 團隊 騰訊Web前端團隊,代表作品WebQQ,致力于前端技術的研究 ISUX 騰...
摘要:一團隊組織網(wǎng)站說明騰訊團隊騰訊前端團隊,代表作品,致力于前端技術的研究騰訊社交用戶體驗設計,簡稱,騰訊設計團隊網(wǎng)站騰訊用戶研究與體驗設計部百度前端研發(fā)部出品淘寶前端團隊用技術為體驗提供無限可能凹凸實驗室京東用戶體驗設計部出品奇舞團奇虎旗下前 一、團隊組織 網(wǎng)站 說明 騰訊 AlloyTeam 團隊 騰訊Web前端團隊,代表作品WebQQ,致力于前端技術的研究 ISUX 騰...
閱讀 2222·2023-04-26 01:57
閱讀 3240·2023-04-25 16:30
閱讀 2325·2021-11-17 09:38
閱讀 1068·2021-10-08 10:14
閱讀 1382·2021-09-23 11:21
閱讀 3678·2019-08-29 17:28
閱讀 3450·2019-08-29 15:27
閱讀 944·2019-08-29 13:04