React——第三階段(1)(高階元件、context)
根據鬍子大哈的文章學習,感謝大胡分享
鬍子大哈-高階元件、context
高階元件
什麼是高階元件
高階元件就是一個函式,傳給他一個元件,他返回一個新的元件。這個新元件會使用傳入的元件作為其子元件。
高階元件體現的是——設計
核心思想:抽象具有相同需求邏輯的元件,用函式處理
例子:
可能有很多元件有這樣需求:“在元件掛載階段,從LocalStorage載入某欄位”
定義高階元件src/Component/wrapWithLoadData.js
:
import React, { Component } from 'react' export default (WrappedComponent, name) => { class NewComponent extends Component { constructor () { super() this.state = { data: null } } componentWillMount () { let data = localStorage.getItem(name) this.setState({ data }) } render () { return <WrappedComponent data={this.state.data} /> } } return NewComponent }
使用高階元件:
import wrapWithLoadData from './wrapWithLoadData'
class InputWithUserName extends Component {
render () {
return <input value={this.props.data} />
}
}
InputWithUserName = wrapWithLoadData(InputWithUserName, 'username')
export default InputWithUserName
可以看到,InputWithUserName
LocalStorage
載入欄位的邏輯,直接是用的高階元件包裝。不用自己再寫了。
那麼高階元件的作用也就一目瞭然了:元件之間程式碼複用。
元件們可能有某些相似的邏輯,把這些邏輯抽象,做成高階元件,來達到複用效果。在高階元件內部,通過props
把資料傳遞給被包裝的元件。
高階元件的靈活性
高階元件本質是裝飾者模式,通過組合方式,達到很高的靈活性。
比如,上邊的InputWithUserName
不從LocalStorage
載入,而是使用Ajax
請求從伺服器載入。那麼,不需要修改元件邏輯,而是新寫一個wrapWithAjaxData
的高階元件,然後包裝InputWithUserName
多層高階元件
兩個高階元件:wrapWithLoadData``wrapWithAjaxData
其中wrapWithAjaxData
具體內容
...
componentWillMount () {
ajax.get('/data/' + this.props.data, (data) => {
this.setState({ data })
})
...
我們的邏輯是,先從localStorage中拿到username,然後根據username從後臺拿到使用者的具體資料。
修改InputWithUserName
import wrapWithLoadData from './wrapWithLoadData'
import wrapWithAjaxData from './wrapWithAjaxData'
class InputWithUserName extends Component {
render () {
return <input value={this.props.data} />
}
}
InputWithUserName = wrapWithAjaxData(InputWithUserName)
InputWithUserName = wrapWithLoadData(InputWithUserName, 'username')
export default InputWithUserName
React.js的context
全域性空間:父元件設定context並放入某狀態,其下每個孩子元件都可以從其取得狀態,而不用一層一層的向下傳遞。(更改了,就會重新渲染一遍)
爺爺元件是訪問不到context的。
寫法
static childContextTypes = {
<key>: PropTypes.<型別>
}
getChildContext () {
return {
<key>: <value>
}
}
childContextTypes
:是為context中的欄位設定型別檢查,必須設定getChildContext()
:用來設定元件的context
若在子元件要使用,可以寫
class Title extends Component {
static contextTypes = {
themeColor: PropTypes.string
}
render () {
return (
<h1 style={{ color: this.context.themeColor }}>React.js 小書標題</h1>
)
}
contextTypes
首先要型別檢查,必須的this.context.<key>
即可獲取
總結
context
打破了元件之間必須通過props
傳遞狀態的過程,類似一個全域性變數空間,其內容能被隨意接觸修改。這樣導致程式不可控。
這種機制,對於狀態管理有很大幫助,redux-react就是充分利用了這個機制。
一般我們動手寫context,而是利用第三方狀態管理庫。
作者:布蕾布蕾
連結:https://www.jianshu.com/p/f05beebc12de
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。