在適合的情況下疚俱,我們都應該且必須使用無狀態(tài)組件劝术。無狀態(tài)組件不像其他兩種方法在調(diào)用時會創(chuàng)建新實例,它創(chuàng)建時始終保持了一個實例呆奕,避免了不必要的檢查和內(nèi)存分配养晋,做到了內(nèi)部優(yōu)化×杭兀——摘自《深入 React 技術(shù)椛》
無狀態(tài)組件
無狀態(tài)組件又稱變現(xiàn)性組件或者木偶組件,為何叫木偶組件姆泻?因為它只關(guān)心數(shù)據(jù)傳遞props
零酪,只能訪問輸入的 props
冒嫡,同樣的 props
會得到同樣的渲染結(jié)果,不會有副作用四苇。
無狀態(tài)組件無法訪問生命周期的方法孝凌,因為它是不需要組件生命周期管理和狀態(tài)管理,所以底層實現(xiàn)這種形式的組件時是不會實現(xiàn)組件的生命周期方法月腋。所以無狀態(tài)組件是不能參與組件的各個生命周期管理的蟀架。
無狀態(tài)組件不會被實例化,無實例化過程也就不需要分配多余的內(nèi)存榆骚,所以相比有狀態(tài)組件辜窑,它的性能更優(yōu)。同樣寨躁,由于沒有實例化穆碎,所以無法訪問組件this
中的對象,例如:this.ref
职恳、this.state
等均不能訪問所禀。若想訪問就不能使用這種形式來創(chuàng)建組件。
它有兩種情況放钦,要么是純粹的渲染 html
內(nèi)容色徘,不需要對數(shù)據(jù)進行判斷和處理。要么這個組件所需要的數(shù)據(jù)操禀,都是來自于父組件props
傳遞來或者 Redux
的 store
中的數(shù)據(jù))褂策,無狀態(tài)組件應該保持模板的純粹性。
const Title = (props) => (
<div className="title-style">
{props.word}
</div>
)
export default Title;
有狀態(tài)組件
有狀態(tài)組件又被稱為容器組件或者聰明組件颓屑,它主要用來處理數(shù)據(jù)或者頁面邏輯交互斤寂。它比無狀態(tài)功能更加強大。類組件可以維護自身的狀態(tài)變量揪惦,即組件的state
遍搞。
有狀態(tài)組件組件還有不同的生命周期方法,可以讓開發(fā)者能夠在組件的不同階段(掛載器腋、更新溪猿、卸載),對組件做更多的控制纫塌。
在React
組件中有狀態(tài)組件相當于一個樞紐站诊县。因為它就像一個容器,里面包含的是無狀態(tài)組件措左,在容器組件中獲取完數(shù)據(jù)后依痊,再將這些數(shù)據(jù)分配給子組件。就像下面的例子媳荒,Title
是一個無狀態(tài)組件抗悍,數(shù)據(jù)在有狀態(tài)組件中處理完在傳遞給給Title
驹饺,
import Title from './Title.js';
class Title extends React.Component{
constructor(props){
super(props);
this.state={
titleWord:'hello world'
}
}
render(){
return(
<div className="title-style">
<Title word={this.state.titleWord}/>
</div>
)
}
}
export default Title;
從性能角度分析兩者區(qū)別
這里摘抄自如何為組件增加狀態(tài)?
通常缴渊,函數(shù)(function
)與類(class
)最大的區(qū)別是:是否能夠維護自己的數(shù)據(jù)(即狀態(tài))赏壹。函數(shù)基本上僅關(guān)注動作(action
),而不關(guān)心數(shù)據(jù)的維護衔沼,不用維持一個狀態(tài)蝌借,不用把自己的數(shù)據(jù)保存在內(nèi)存中。函數(shù)使用的數(shù)據(jù)是從外部獲戎敢稀(或者不獲取數(shù)據(jù))菩佑,函數(shù)運行時,會完成一系列的動作凝化,最后將結(jié)果返回(也可能不返回稍坯,僅僅是完成指定的動作)。相對而言搓劫,類有能力維護狀態(tài)(保存數(shù)據(jù))瞧哟,也可以定義自己的一系列動作。
一般來說枪向,函數(shù)的速度較快勤揩,適合用于做表現(xiàn)層,而類能夠處理復雜邏輯和狀態(tài)秘蛔,適合做邏輯層和數(shù)據(jù)層陨亡。所以,對于 React
來說深员,一般選擇函數(shù)來無狀態(tài)組件负蠕,得到所謂的無狀態(tài)函數(shù)(stateless function
),好處是渲染的速度快辨液,所以多使用無狀態(tài)組件虐急,盡量不要讓數(shù)據(jù)散落在各個組件中。數(shù)據(jù)集中管理可以更好的保持數(shù)據(jù)的一致性和可維護性滔迈。
有狀態(tài)組件就是使用類來生成。類可以有自己的狀態(tài)被辑,維護自己的數(shù)據(jù)燎悍,也是完全符合有狀態(tài)組件的要求。但是類相對來說速度比函數(shù)慢盼理,影響渲染的性能谈山,同時數(shù)據(jù)過于分散會給后期的維護帶來比較大的困難(這也是為什么狀態(tài)過多時要使用 Redux
的原因),因此要盡量控制有狀態(tài)組件的數(shù)量宏怔。當然奏路,類也可以生成無狀態(tài)組件畴椰,但是既然不需要維護狀態(tài)的工作,用函數(shù)能完成得更好鸽粉,其實也就沒有必要使用類來做無狀態(tài)組件斜脂。