簡評:據作者說,練成絕招后副作用就是手會發紅,屁股變壞。
所有你所需要知道的關于 React 的內容可以歸結為 五個關鍵概念。
這五個關鍵概念就是:
- 組件
- JSX 語法
- 屬性 & 狀態
- 組件 API
- 組件類型
概念 #1: React 組件是如何工作的
你所需要了解的關于 React 的第一件事就是關于組件的事。你的 React 代碼庫就是一大堆大組件調用更小的組件。
什么是組件呢?組件完美的例子就是常見的 <select> HTML 元素。它不僅有視覺輸出(灰色框,文字標簽,向下的箭頭組成了這個元素)——而且還處理自己的開閉邏輯。
現在想象用自己的樣式和行為組建自定義的 <select> 元素。
那么,這恰恰就是 React 讓你做的事。一個 React 組件是一個單一的對象,不僅輸出像傳統模板一樣的 HTML,而且包括了控制該輸出的所有代碼。
在實踐中,寫 React 組件最為普遍的方式就是用 ES6 class 包含一個返回 HTML 的 render 方法(還有一個超級秘密的函數的方式,但你要等到第四個概念才能了解它):
class MyComponent extends React.Component {
render() {
return <p>Hello World!<p>;
}
}
概念 #2: JSX 是如何工作的
你可以看到,組件文件同時包含 HTML 和 JavaScript 代碼。React 的秘密武器就是 JSX 語言(“X” 代表 “XML”)。JSX 可能一開始看起來很難對付,但你很快就能熟悉它。
我們都被教導要保持 HTML 和 JavaScript 的強大分離。但是當放松這個規則后,你能在你的前端產品中做一些驚奇的事。
比如,因為你現在擁有 JavaScript 的完整功能,你可以在 HTML 中使用 {...} 插入 JavaScript 片段來展示當前時間:
class MyComponent extends React.Component {
render() {
return <p>Today is: {new Date()}</p>;
}
}
這同樣意味著你將使用純 JavaScript for,if 語句或循環,而不是某種特定于模板的語法。JavaScript 的三元運算符在這里特別方便。
class MyComponent extends React.Component {
render() {
return <p>Hello {this.props.someVar ? 'World' : 'Kitty'}</p>;
}
}
順帶一提,作者推薦 ES6 語法,喜歡視頻的可以看 ES6 for Everyone,喜歡閱讀的可以看 Practical ES6。
概念 #3: 屬性 & 狀態 是如何工作的
可能你會想要知道上面的 this.props.someVar 變量是怎么來的。如果你寫過一行 HTML,你可能熟悉 HTML 的屬性比如<a>
標簽的 href。在 React 中,屬性表示為 props (properties 的縮寫)。Props 是組件如何溝通的方式。
class ParentComponent extends React.Component {
render() {
return <ChildComponent message="Hello World"/>;
}
}
class ChildComponent extends React.Component {
render() {
return <p>And then I said, “{this.props.message}”</p>;
}
}
因為這個,React 的數據流是單向的。數據只能從父組件流向子組件,而不是相反的方式。
盡管有時候,一個組件做出反應的數據不是來自于父組件(比如用戶輸入)。這就是** state **怎么來的。
要理解 props 和 state 的不用之處,一個很好的比喻就是 Etch-A-Sketch 平板。與 Etch-A-Sketch 的身體顏色和撥號位置(props)不同,繪圖(state)本身不是 Etch-A-Sketch 的固有屬性,而僅僅是用戶輸入的臨時結果。
注意組件的狀態同樣可以作為屬性傳遞給它的子組件。你可以理解成一條大河從高山上流下來,隨著路由,數據層,以及各種組件把它們的數據像小溪一樣匯入,組成主要的 app 狀態。
在組件中,狀態用 setState 方法來管理,通常在事件處理器中調用。
class MyComponent extends React.Component {
handleClick = (e) => {
this.setState({clicked: true});
}
render() {
return <a href="#" onClick={this.handleClick}>Click me</a>;
}
}
在實踐中,React 應用中大多數數據是屬性。僅僅當你需要接收用戶輸入時,你需要用狀態來處理變化。
注意到我們使用箭頭函數來綁定 handleClick 處理器,你可以在這里學到更多。
概念 #4: 組件 API 是如何工作的
我們已經提到了 render 和 setState,兩者都是組件 API 方法的一部分。另一個有用的是 constructor,你可以用來初始化你的狀態和綁定方法。
除了這三個函數,React還提供了在組件生命周期(加載前,加載后,卸載后等等)內的各個點觸發的一組回調。除非你做一些高級的 React 巫術,你將可能從不需要擔心這些。
這節看起來很短,因為學習 React 實際上更多的是精通編程和架構的概念而不是學習一系列無聊的 API。它看起來如此清爽!
概念 #5: 組件類型是如何工作的
我們已經見識過如何使用類來定義一個組件:
class MyComponent extends React.Component {
render() {
return <p>Hello World!<p>;
}
}
并且我們還討論了這些類支持的組件方法。現在忘掉它們!越來越多的人將 React 組件寫成函數式組件。
一個函數式組件是一個函數,它使用 props 對象作為參數,并且返回一串 HTML。幾乎就像一個傳統的模板,關鍵的不同是在你需要的時候,你仍然可以在其中使用任何 JavaScript 代碼:
const myComponent = props => {
return <p>Hello {props.name}! Today is {new Date()}.</p>
}
使用函數式組件語法的結果就是你失去了進入我們之前說的組件方法的權利。但事實證明,這是非常好的,因為絕大多數的組件可能不需要它們。
順便一提,其中的一個方法是 setState,這意味著函數式組件不能有狀態。因為這個原因,它們被通常被成為無狀態函數組件。
由于函數式組件需要的樣板代碼少得多,盡可能使用它們是有意義的。因此,大多數 React 應用程序都包含兩種語法的健康組合。
請注意還有第三個使用 createClass 函數的舊語法,任何使用它的人應該感到羞愧和被點名批評,因為大膽到使用 18 個月前的編程模式:
var Greeting = React.createClass({
render: function() {
return <h1>Hello, {this.props.name}</h1>;
}
});
其實有彩蛋,還有第六個概念,請戳原文:
原文鏈接:React’s Five Fingers of Death. Master these five concepts, then master React.
延伸閱讀:
- JavaScript 數組和對象就像書和報紙一樣
- 極光開源項目:「Aurora UI」,一個通用 IM 聊天 UI 組件,正在努力支持react中。