[TOC]
# Making a functional or stateless component
So far, we have only learned how to create *class components* in React. These components are useful when you need to handle local state, but in some cases, we will need to render static markup. For static components, we need to use functional components, also known as stateless components . This will improve the performance of our application.
到目前為止,我們只學習了如何在React中創建類組件。當您需要處理本地狀態時,這些組件非常有用,但是在某些情況下,我們需要渲染靜態標記。對于靜態組件,我們需要使用 functional components ,也稱為stateless components 無狀態組件。這將提高應用程序的性能。
In the *Passing props to a component and validating them with PropTypes* recipe, we created some layout components (`Header`, `Content`, and `Footer`).
These components, as you may imagine, are frequently not dynamic (unless you want to have a toggle menu or some user information in the header), so in this case, we can convert them into functional components.
你可能想到,這些組件通常不是動態的(除非你想在標題中有一個切換菜單或一些用戶信息),所以在這種情況下,我們可以將它們轉換為 功能組件。
# getInitialState VS constructor
`React.createClass`創建了一個叫做`getInitialState`的函數,它只做一件事,那就是返回一個包含初始化狀態的對象。
使用`React.Component`后,`getInitialState`函數被拋棄了,我們在`constructor`中像創建初始化屬性一樣聲明了所有狀態,我認為這樣更加像 JavaScript 并且更少地驅動了“API”。
也就是說,`React.createClass`創建的組件,其狀態`state`是通過`getInitialState`方法來配置組件相關的狀態;`React.Component`創建的組件,其狀態`state`是在`constructor`中像初始化組件屬性一樣聲明的。
# Mixins
Mixins(混入)是面向對象編程OOP的一種實現,其作用是為了復用共有的代碼,將共有的代碼通過抽取為一個對象,然后通過Mixins進該對象來達到代碼復用。如果我們使用 ES6 的方式來創建組件,那么 React mixins 的特性將不能被使用了。
## React.createClass
使用`React.createClass`的話,我們可以在創建組件時添加一個叫做`mixins`的屬性,并將可供混合的類的集合以數組的形式賦給`mixins`。
```
import React from 'react';
var SomeMixin = {
doSomething() {
}
};
const Contacts = React.createClass({
mixins: [SomeMixin],
handleClick() {
this.doSomething(); // use mixin
},
render() {
return (
<div onClick={this.handleClick}></div>
);
}
});
export default Contacts;
```
## React.Component
**但在 ES6 中,`mixins`特性不被支持。但是 React 社區提供一個全新的方式來取代 Mixins ,那就是 Higher-Order Components(高階組件)**。 那么什么是高階組件呢?其實它和高階函數的概念類似,就是一個會返回組件的組件。或者更確切地說,它其實是一個會返回組件的函數。就像這樣:
```
const HigherOrderComponent = (WrappedComponent) => {
return class WrapperComponent extends Component {
render() {
//do something with WrappedComponent
}
}
}
```
做為一個高階組件,可以在原有組件的基礎上,對其增加新的功能和行為。我們一般希望編寫的組件盡量純凈或者說其中的業務邏輯盡量單一。
但是如果各種組件間又需要增加新功能,如打印日志,獲取數據和校驗數據等和展示無關的邏輯的時候,這些公共的代碼就會被重復寫很多遍。
因此,我們可以抽象出一個高階組件,用以給基礎的組件增加這些功能,類似于插件的效果。具體細節可以[參考這篇文章](https://leozdgao.me/chushi-hoc/)。
# 無狀態組件
無狀態組件一般會搭配**高階組件**(簡稱:HOC)一起使用,高階組件用來托管`state`,Redux 框架就是通過`store`管理數據源和所有狀態,其中所有負責展示的組件都使用無狀態函數式的寫法。
這種模式被鼓勵在大型項目中盡可能以簡單的寫法 來分割原本龐大的組件,**而未來 React 也會面向這種無狀態的組件進行一些專門的優化,比如避免無意義的檢查或內存分配。所以建議大家盡可能在項目中使用無狀態組件。**
無狀態組件內部其實是可以使用 `ref` 功能的,雖然不能通過 `this.refs` 訪問到,但是可以通過將 `ref` 內容保存到無狀態組件內部的一個本地變量中獲取到。
例如下面這段代碼可以使用 `ref` 來獲取組件掛載到DOM中后所指向的DOM元素:
```
function TestComp(props){
let ref;
return (
<div ref={(node) => ref = node}></div>
)
}
```