React.js 小書 Lesson11 - 配置元件的 props
React.js 小書 Lesson11 - 配置元件的 props
轉載請註明出處,保留原文連結以及作者資訊
線上閱讀:http://huziketang.com/books/react
元件是相互獨立、可複用的單元,一個元件可能在不同地方被用到。但是在不同的場景下對這個元件的需求可能會根據情況有所不同,例如一個點贊按鈕元件,在我這裡需要它顯示的文字是“點贊”和“取消”,當別的同事拿過去用的時候,卻需要它顯示“贊”和“已贊”。如何讓元件能適應不同場景下的需求,我們就要讓元件具有一定的“可配置”性。
React.js 的 props
就可以幫助我們達到這個效果。每個元件都可以接受一個 props
引數,它是一個物件,包含了所有你對這個元件的配置。就拿我們點贊按鈕做例子:
[圖片上傳失敗...(image-a90954-1510226306876)]
下面的程式碼可以讓它達到上述的可配置性:
class LikeButton extends Component {
constructor () {
super()
this.state = { isLiked: false }
}
handleClickOnLikeButton () {
this.setState({
isLiked: !this.state.isLiked
})
}
render () {
const likedText = this.props.likedText || '取消'
const unlikedText = this.props.unlikedText || '點贊'
return (
<button onClick={this.handleClickOnLikeButton.bind(this)}>
{this.state.isLiked ? likedText : unlikedText} ?
</button>
)
}
}
從 render
函式可以看出來,元件內部是通過 this.props
的方式獲取到元件的引數的,如果 this.props
裡面有需要的屬性我們就採用相應的屬性,沒有的話就用預設的屬性。
那麼怎麼把 props
傳進去呢?在使用一個元件的時候,可以把引數放在標籤的屬性當中,所有的屬性都會作為 props
物件的鍵值:
class Index extends Component {
render () {
return (
<div>
<LikeButton likedText='已贊' unlikedText='贊' />
</div>
)
}
}
就像你在用普通的 HTML 標籤的屬性一樣,可以把引數放在表示元件的標籤上,元件內部就可以通過 this.props
來訪問到這些配置引數了。
[圖片上傳失敗...(image-401123-1510226306876)]
前面的章節我們說過,JSX 的表示式插入可以在標籤屬性上使用。所以其實可以把任何型別的資料作為元件的引數,包括字串、數字、物件、陣列、甚至是函式等等。例如現在我們把一個物件傳給點贊元件作為引數:
class Index extends Component {
render () {
return (
<div>
<LikeButton wordings={{likedText: '已贊', unlikedText: '贊'}} />
</div>
)
}
}
現在我們把 likedText
和 unlikedText
這兩個引數封裝到一個叫 wordings
的物件引數內,然後傳入點贊元件中。大家看到 {{likedText: '已贊', unlikedText: '贊'}}
這樣的程式碼的時候,不要以為是什麼新語法。之前討論過,JSX 的 {}
內可以嵌入任何表示式,{{}}
就是在 {}
內部用物件字面量返回一個物件而已。
這時候,點贊按鈕的內部就要用 this.props.wordings
來獲取到到引數了:
class LikeButton extends Component {
constructor () {
super()
this.state = { isLiked: false }
}
handleClickOnLikeButton () {
this.setState({
isLiked: !this.state.isLiked
})
}
render () {
const wordings = this.props.wordings || {
likedText: '取消',
unlikedText: '點贊'
}
return (
<button onClick={this.handleClickOnLikeButton.bind(this)}>
{this.state.isLiked ? wordings.likedText : wordings.unlikedText} ?
</button>
)
}
}
甚至可以往元件內部傳入函式作為引數:
class Index extends Component {
render () {
return (
<div>
<LikeButton
wordings={{likedText: '已贊', unlikedText: '贊'}}
onClick={() => console.log('Click on like button!')}/>
</div>
)
}
}
這樣可以通過 this.props.onClick
獲取到這個傳進去的函式,修改 LikeButton
的 handleClickOnLikeButton
方法:
...
handleClickOnLikeButton () {
this.setState({
isLiked: !this.state.isLiked
})
if (this.props.onClick) {
this.props.onClick()
}
}
...
當每次點選按鈕的時候,控制檯會顯示 Click on like button!
。但這個行為不是點贊元件自己實現的,而是我們傳進去的。所以,一個元件的行為、顯示形態都可以用 props
來控制,就可以達到很好的可配置性。
預設配置 defaultProps
上面的元件預設配置我們是通過 ||
操作符來實現。這種需要預設配置的情況在 React.js 中非常常見,所以 React.js 也提供了一種方式 defaultProps
,可以方便的做到預設配置。
class LikeButton extends Component {
static defaultProps = {
likedText: '取消',
unlikedText: '點贊'
}
constructor () {
super()
this.state = { isLiked: false }
}
handleClickOnLikeButton () {
this.setState({
isLiked: !this.state.isLiked
})
}
render () {
return (
<button onClick={this.handleClickOnLikeButton.bind(this)}>
{this.state.isLiked
? this.props.likedText
: this.props.unlikedText} ?
</button>
)
}
}
注意,我們給點贊元件加上了以下的程式碼:
static defaultProps = {
likedText: '取消',
unlikedText: '點贊'
}
defaultProps
作為點贊按鈕元件的類屬性,裡面是對 props
中各個屬性的預設配置。這樣我們就不需要判斷配置屬性是否傳進來了:如果沒有傳進來,會直接使用 defaultProps
中的預設屬性。 所以可以看到,在 render
函式中,我們會直接使用 this.props
而不需要再做判斷。
props 不可變
props
一旦傳入進來就不能改變。修改上面的例子中的 handleClickOnLikeButton
:
...
handleClickOnLikeButton () {
this.props.likedText = '取消'
this.setState({
isLiked: !this.state.isLiked
})
}
...
我們嘗試在使用者點選按鈕的時候改變 this.props.likedText
,然後你會看到控制檯報錯了:
[圖片上傳失敗...(image-30fcab-1510226306876)]
你不能改變一個元件被渲染的時候傳進來的 props
。React.js 希望一個元件在輸入確定的 props
的時候,能夠輸出確定的 UI 顯示形態。如果 props
渲染過程中可以被修改,那麼就會導致這個元件顯示形態和行為變得不可預測,這樣會可能會給元件使用者帶來困惑。
但這並不意味著由 props
決定的顯示形態不能被修改。元件的使用者可以主動地通過重新渲染的方式把新的 props
傳入元件當中,這樣這個元件中由 props
決定的顯示形態也會得到相應的改變。
修改上面的例子的 Index
元件:
class Index extends Component {
constructor () {
super()
this.state = {
likedText: '已贊',
unlikedText: '贊'
}
}
handleClickOnChange () {
this.setState({
likedText: '取消',
unlikedText: '點贊'
})
}
render () {
return (
<div>
<LikeButton
likedText={this.state.likedText}
unlikedText={this.state.unlikedText} />
<div>
<button onClick={this.handleClickOnChange.bind(this)}>
修改 wordings
</button>
</div>
</div>
)
}
}
在這裡,我們把 Index
的 state
中的 likedText
和 unlikedText
傳給 LikeButton
。Index
還有另外一個按鈕,點選這個按鈕會通過 setState
修改 Index
的 state
中的兩個屬性。
由於 setState
會導致 Index
重新渲染,所以 LikedButton
會接收到新的 props
,並且重新渲染,於是它的顯示形態也會得到更新。這就是通過重新渲染的方式來傳入新的 props
從而達到修改 LikedButton
顯示形態的效果。
總結
- 為了使得元件的可定製性更強,在使用元件的時候,可以在標籤上加屬性來傳入配置引數。
- 元件可以在內部通過
this.props
獲取到配置引數,元件可以根據props
的不同來確定自己的顯示形態,達到可配置的效果。 - 可以通過給元件新增類屬性
defaultProps
來配置預設引數。 -
props
一旦傳入,你就不可以在元件內部對它進行修改。但是你可以通過父元件主動重新渲染的方式來傳入新的props
,從而達到更新的效果。
下一節中我們將介紹《React.js 小書 Lesson12 - state vs props》。
相關文章
- React.js 小書 Lesson12 – state vs propsReactJS
- React.js 實戰 - 元件 & PropsReactJS元件
- React.js 小書 Lesson4 – 前端元件化(三):抽象出公共元件類ReactJS前端元件化抽象
- React.js 小書 Lesson4 - 前端元件化(三):抽象出公共元件類ReactJS前端元件化抽象
- React.js 小書 Lesson21 – ref 和 React.js 中的 DOM 操作ReactJS
- React之配置元件的props(兩個例項)React元件
- react進階元件之Render Props小結React元件
- 【Vue】元件 - 驗證propsVue元件
- 為什麼更新父元件的非props屬性,子元件 props watch 會觸發?元件
- React.js 中的元件通訊問題ReactJS元件
- Benchmarksql的props配置檔案解析SQL
- vue元件通訊之propsVue元件
- 【vue元件通訊①】父元件向子元件通訊propsVue元件
- vue 父元件props傳值子元件時 的更新問題Vue元件
- 無配置建立React.js應用ReactJS
- vue3 元件中props,emits用法Vue元件MIT
- react 也就這麼回事 05 —— 元件 & PropsReact元件
- vue使用的props元件傳值問題處理Vue元件
- 元件引數校驗與非props特性元件
- Vue : props 使用細節(父元件傳遞資料給子元件)Vue元件
- vue3 父元件【屬性】傳值給子元件【props】接收Vue元件
- Vue元件之props,$emit與$on以及slot分發Vue元件MIT
- vue3元件通訊與propsVue元件
- 筆記1:vue 利用props 父到子元件傳值(初識元件)筆記Vue元件
- React Native 探索(三)元件的 Props (屬性) 和 State (狀態)React Native元件
- 記如何解決vue父元件改變不了子元件props傳過來的陣列Vue元件陣列
- vue 父元件在created中傳值給子元件,子元件去監聽props變化Vue元件
- Render props、render callback 和高階元件皆可互換[譯]元件
- vue.js使用props在父子元件之間傳參Vue.js元件
- props
- IOS Widget(4-1):建立可配置小元件(靜態配置資料)iOS元件
- Lesson11——Pandas去重函式:drop_duplicates()函式
- [React.js]元件解除安裝如何自動取消非同步請求ReactJS元件非同步
- Vue 中,如何將函式作為 props 傳遞給元件Vue函式元件
- IOS小元件(7):小元件點選互動iOS元件
- React的this.props.childrenReact
- vue之父子元件間通訊例項講解(props、$ref、$emit)Vue元件MIT
- 配置Seam元件元件