Hi!恭喜踏入第11篇!完成1/3的賽程了!這樣子一直倒數心態是不是不太好XD,不過我還是很沈醉在給自己壓力的,哈哈哈,但是結束後還是讓我耍廢一陣子吧!欸?現在講這個好像太早XD,哈哈哈,那在結束前讓大家多陪我一下吧!
今天要說的是React的組件構成模式,哈哈,就把標題再說一次。
這篇應該比較算是小技巧,主要會繞在props
上,相信經過前10天再扣掉webpack
的2天,共8天的考驗,現在各位應該對props
不陌生了,一開始知道他可以傳入值,昨天又知道他連function
都可以傳入,那除此之外呢?讓我們接著看下去!
首先假設我們有一個簡單的組件,裡面有個簡單的div
,而為了讓他看起來明顯,在設定他的背景顏色為灰色:
class MessageBlock extends React.Component {
constructor(props){
super(props)
this.state = ({style:{backgroundColor:'#DDDDDD',height:200,width:'100%'}})
}
render(){
return <div style={this.state.style}></div>
}
}
ReactDOM.render(<MessageBlock />, document.getElementById('root'))
結果如下:
感覺根本沒有展示的必要XD
那接下來我們建立另一個組件Message
,如下:
class Message extends React.Component{
constructor(props){
super(props)
this.state = ({style:{backgroundColor:'#FFFFFF',height:100,width:'80%'}})
}
render(){
return <div style={this.state.style}>
{this.props.children}
</div>
}
}
這個組件寫好後先暫停一下,我們把視線留在{this.props.children}
上面,乍看之下沒什麼奇怪,不就設定一個props
,然後透過children
傳入值嗎?有什麼奇怪的?欸嘿嘿!繼續跟著我一探究竟吧!
下方把Message
組件寫進MessageBlock
中:
class Message extends React.Component{
constructor(props){
super(props)
this.state = ({style:{backgroundColor:'#FFFFFF',height:100,width:'80%'}})
}
render(){
return <div style={this.state.style}>
{this.props.children}
</div>
}
}
class MessageBlock extends React.Component {
constructor(props){
super(props)
this.state = ({style:{backgroundColor:'#DDDDDD',height:200,width:'100%'}})
}
render(){
return (
<div style={this.state.style}>
<Message>
<p>組件標籤內的內容會被傳到該組件的props.children中</p>
</Message>
</div>)
}
}
ReactDOM.render(<MessageBlock />, document.getElementById('root'))
結果如下:
登愣!有看出來什麼端倪嗎?上方在使用Message
的時候並沒有使用children='XXX'
將值或是任何東西傳進去,但是渲染出來的畫面居然會有內容!原因是因為props.children
的值會預設傳入被該組件包夾的內容也就是JSX
,所以我們可以透過它來補洞!
不過凡事都有但書,假如要補的洞有兩個該怎麼辦?像是把Message
改成下方這樣:
class Message extends React.Component{
constructor(props){
super(props)
this.state = ({style:{backgroundColor:'#FFFFFF',height:100,width:'80%'}})
}
render(){
return (<div>
<div style={this.state.style}>
{this.props.userName}
</div>
<div style={this.state.style}>
{this.props.message}
</div>
</div>)
}
}
需要同時傳入userName
及message
該怎麼做?children
只有一個啊!
別慌,那不就照正常的方式傳入就好了嗎:)
class MessageBlock extends React.Component {
constructor(props){
super(props)
this.state = ({style:{backgroundColor:'#DDDDDD',height:200,width:'100%'}})
}
render(){
return (
<div style={this.state.style}>
<Message userName="GQSM" message="Hello!大家好!" />
</div>)
}
}
結果會如下:
要傳入事件也可以,而且因為JSX
是透過props
傳入的,所以可以直接設定事件:
class MessageBlock extends React.Component {
constructor(props){
super(props)
this.state = ({style:{backgroundColor:'#DDDDDD',height:200,width:'100%'}})
this.writeMessageConsole = this.writeMessageConsole.bind(this)
}
//宣告事件
writeMessageConsole(event){
console.log(event.target.innerText)
}
render(){
return (
<div style={this.state.style}>
<Message>
{/*不需要使用this.props.writeMessageConsole,
可直接使用this.writeMessageConsole依然會執行*/}
<p onClick={this.writeMessageConsole}>組件標籤內的內容會被傳到該組件的props.children中</p>
</Message>
</div>)
}
}
結果會如下:
也可以直接傳入組件哦!讓我們再新增一個組件MessageContent
:
class Message extends React.Component{
constructor(props){
super(props)
this.state = ({style:{backgroundColor:'#FFFFFF',height:100,width:'80%'}})
}
render(){
return <div style={this.state.style}>
{this.props.children}
</div>
}
}
class MessageContent extends React.Component {
render(){
return <p>組件標籤內的內容會被傳到該組件的props.children中</p>
}
}
接著改寫MessageBlock
組件的內容,在Message
組件中放入MessageContent
:
class MessageBlock extends React.Component {
constructor(props){
super(props)
this.state = ({style:{backgroundColor:'#DDDDDD',height:200,width:'100%'}})
}
render(){
return (
<div style={this.state.style}>
<Message>
<MessageContent />
</Message>
</div>)
}
}
如此一來,Message
中的this.props.children
也會接收到MessageContent
回傳的組件內容哦!
最後的貼心小題醒,如果在組件中同時傳入children
,傳進去的資料會以被組件包括的內容為主:
class Message extends React.Component{
constructor(props){
super(props)
this.state = ({style:{backgroundColor:'#FFFFFF',height:100,width:'80%'}})
}
render(){
return <div style={this.state.style}>
{this.props.children}
</div>
}
}
class MessageBlock extends React.Component {
constructor(props){
super(props)
this.state = ({style:{backgroundColor:'#DDDDDD',height:200,width:'100%'}})
}
render(){
return (
<div style={this.state.style}>
<Message children="從props傳進內容">
<p>props.children的內容會以這裡為主</p>
</Message>
</div>)
}
}
ReactDOM.render(<MessageBlock />, document.getElementById('root'))
結果會如下:
react
中的props
真的很方便,連組件都可以透過props
傳入子組件中,所以react
特別注重在組件的組合和結構,而不是用繼承來擴充組件原本的樣子,聽說用react
所寫的facebook
中連一個關於組件繼承的例子都沒有!所以把組件的使用方式學起來,就在畫面上得天下了!
最後感謝各位大大的觀看,如果上方有任何不清楚或錯誤的地方,還請大大們留言告訴我,我會再盡快修正和補充文章內容的!謝謝大家
參考文章: