React中的組件主要分爲無狀態組件和有狀態組件兩類。函數
1,無狀態組件主要用來定義模板,接收來自父組件props傳遞過來的數據,使用{props.xxx}的表達式把props塞到模板裏面。無狀態組件應該保持模板的純粹性,以便於組件複用。建立無狀態組件以下:this
var Header = (props) = ( <div>{props.xxx}</div> );
2,有狀態組件主要用來定義交互邏輯和業務數據(若是用了Redux,能夠把業務數據抽離出去統一管理),使用{this.state.xxx}的表達式把業務數據掛載到容器組件的實例上(有狀態組件也能夠叫作容器組件,無狀態組件也能夠叫作展現組件),而後傳遞props到展現組件,展現組件接收到props,把props塞到模板裏面。建立有狀態組件以下:spa
class Home extends React.Component { constructor(props) { super(props); }; render() { return ( <Header/> //也能夠寫成<Header></Header> ) } }
這個是官方默認的寫法,在構造函數裏面默認要傳遞一個參數進去,而且要調用super()方法,來獲取子類的實例。可是比較疑惑的地方是爲何要傳遞這些參數,傳遞這些參數有什麼用?code
由於從render()裏面的組件來看,構造函數不傳遞參數也能夠獲取到組件實例上的props屬性。以下:blog
class Home extends React.Component { constructor() { super(); }; render (){ return( <div> <Header name="俺是子組件實例上props屬性"/> </div> ); }; }; class Header extends React.Component { constructor() { super(); }; render() { return ( <div>{this.props.name}</div> //構造函數中並無傳遞props屬性,這裏經過{this.props.name}依然獲取到了值 ); }; };
這個比較好理解,由於render()方法是子組件原型上的方法,獲取實例屬性的時候要經過this來訪問,若是去掉this就獲取不到了。圖片
那問題來了,若是咱們要在構造函數中訪問props改怎麼辦呢?此時,咱們就要在constructor構造函數中傳遞一個props參數,這樣就能夠訪問到子組件實例上的props屬性了。以下:文檔
class Header extends React.Component { constructor(props) { super(); this.name = props.name; //獲取到子組件實例上的props.name屬性,賦值給實例屬性name }; render() { return ( <div>{this.name}</div> ); }; };
還有一個問題,super(props)方法中爲何也要傳遞一個props屬性呢?看下面的例子:原型
class Header extends React.Component { constructor(props) { super(props); this.state = { nameOne: props.name, nameTwo: this.props.name //super()方法中傳遞了props屬性,this.props才能夠獲取到name屬性 } }; render() { return ( <div>{this.state.nameOne}{this.state.nameTwo}</div> ); }; };
其實,props.name和this.props.name的值都是同樣的,可是它倆仍是有區別的,props.name中這個props就是子組件的屬性props,可是this.props.name中的這個props卻不是子組件的屬性props,雖然值都是同樣的,這個props其實在調用super方法的時候被傳遞到了Component這個父類中去了,因此this.props.name獲取到的是Component父類中的props屬性。看下React的源碼:源碼
發現沒,子類super方法把props參數傳遞給了父類Component,Component把props參數掛載到它的實例屬性props上了。因此,你只有給super方法中傳遞props參數,在構造函數裏才能用this,props.xxxit
若是super方法中不傳遞props參數,獲取this.props.name的值就會報錯。獲取this.props顯示爲undifined:以下:
class Header extends React.Component { constructor(props) { super(); this.state = { nameOne: this.props.name, nameTwo: this.props }; console.log(this.props.name); //報錯 console.log(this.props); //undifined }; render() { return ( <div>{this.state.nameOne}{this.state.nameTwo}</div> ); }; };
這種寫法本質是給子組件Header的實例屬性state.nameOne和state.nameTwo賦值了一個子組件Header的實例屬性props,簡單來講,就是Header子組件建立了一個state屬性,而後又把本身的props屬性賦值給了本身的state屬性。
爲何this.props打印出undefined?由於props是調用子組件的時候傳入的參數,因此在構造函數內部是訪問不到props的,那麼對於this.props.name來講,毫無疑問確定報錯。
因此,對與構造函數中的props參數和super中的props參數來講,若是你不在構造函數中用this.props和props,徹底能夠不用傳參。反之就要傳參。可是對於this.props和props來講獲取到的值都是同樣的,因此寫哪一個均可以。可是官方文檔上是兩個參數都有寫。因此爲了嚴謹,仍是都寫上吧。
可是,我我的仍是喜歡這樣的寫法。
constructor(props) { super(props); this.state = { name: props.name } };
不加this的是value,加了this的是key。