React使用新版Context構建元件樹工具注入
一、倉庫地址
本文章基於React@16.3.0,講解我是如何使用新版Context api做工具注入的。github地址
二、為什麼要向元件注入工具
打個比方,在一個元件樹中,通常可能會有多個元件會使用到ajax請求伺服器獲取資料,這時候你就必須在每個元件中引入ajax相關的庫才能使用,如下:
import ajax from `ajax`
export default class App extends Component {
...
componentDidMount () {
ajax.get(`http://xxx.com/a`)
.then(res => {
...
})
}
...
}
而每個元件對於工具的依賴也不相同,那麼則會有相當多的庫引入語句。
// a.jsx
import ajax from `ajax`
//b.jsx
import ajax from `ajax`
import storage from `storage`
然而我並不想每一個元件在我需要用到這種基礎工具的時候都要去單獨引入這些工具,那麼對於多入口的react專案來說,我們可不可以在入口處讓工具存放在元件樹的頂層,需要的時候我就將頂層的工具注入到對應的子元件,然後通過this去訪問對應的工具進行使用呢
// 通過引入一個註解就可以注入頂層放置的工具函式
import { injectMethods } from `provider`
@injectMethods
export default class TestProvider extends Component {
...
componentDidMount () {
this.props.ajax.get(`http://xxx.com/a`)
.then(res => {
...
})
this.props.storage.setItem(`key`, `value`)
}
...
}
這樣我們就不需要關注元件的工具引入了,統一在頂層進行管理,當然你也可以注入其餘的全域性屬性
三、實現
新版的React採取宣告式的方式使用Context api,這是react官方Context用法的說明,下面我們先看看我們的入口是如何將工具儲存在頂層的Provider中的
// 入口js
// provider webpack中定義了alias
import { setProvider } from `provider`
import detectAgent from `provider/detect-agent`
import dateFormat from `provider/format/date-format`
import storage from `provider/storage`
import urlutils from `provider/url-utils`
// 頂層需要注入的方法
let providers = Object.assign(
{},
detectAgent,
dateFormat,
storage,
urlutils
)
render(
// Context.Provider注入方法,供子元件使用
setProvider(App, providers),
document.getElementById(`app`)
)
// provider/index.js
export const Context = React.createContext()
// 傳入根節點與基礎工具,採用Context.Provider對跟元件進行包裝
export const setProvider = (RootComponent, providers) => {
return (
<Context.Provider value={providers}>
<RootComponent></RootComponent>
</Context.Provider>
)
}
/**
* 用註解@的方式給子元件注入全域性方法
* @param {component} RealComponent
*
* 如: @injectMethods
* class TestComponent extends Component {}
*
* 通過上面的方式就可將儲存在頂層的方法注入進元件的props屬性中
*/
export const injectMethods = (RealComponent) => {
return class extends Component {
render () {
return (
<Context.Consumer>
{ value => <RealComponent {...value} {...this.props}></RealComponent> }
</Context.Consumer>
)
}
}
}
在入口檔案中,我們會將方法統一放置在Context.Provider元件中,之後通過Context.Consumer元件去獲取Provider中儲存的value,將工具注入到子元件的props中,injectMethods是一個註解,如果你的一個元件需要獲取頂層的工具,直接在元件上進行註解就可以注入到props中了
import { injectMethods } from `provider`
// 給TestProvider的props注入頂層的方法
@injectMethods
export default class TestProvider extends Component {
componentDidMount () {
// 任意元件都可通過injectMethods注入全域性方法
console.log(`test-provider已向props注入全域性方法`)
console.log(this.props)
}
render () {
let { $dateFormat } = this.props;
return (
<div>
<p>test-provider</p>
<p>{ $dateFormat(new Date()) }</p>
</div>
)
}
}
當然,這種方式還可以對統一對元件樹中的一些常量進行管理,需要的時候就注入到props中使用。
原文釋出時間為:2018年06月28日
原文作者:bug給我滾
本文來源: 掘金 如需轉載請聯絡原作者
相關文章
- 如何快速構建React元件庫React元件
- 構建自己的React UI元件庫: 構建首頁ReactUI元件
- 一個簡單的構建React元件動畫方案React元件動畫
- React + Storybook + Lerna 構建自己的前端UI元件庫React前端UI元件
- 掌握 React 元件樹遍歷技巧React元件
- 構建自己的React UI元件庫(三):文件編寫ReactUI元件
- [譯] 為多個品牌和應用構建 React 元件React元件
- 使用React構建精簡版本掘金(四)React
- 使用React構建精簡版本掘金(三)React
- 使用React構建精簡版本掘金(二)React
- 使用React構建精簡版本掘金(一)React
- 使用Vite快速構建前端React專案Vite前端React
- 安卓架構元件-依賴注入安卓架構元件依賴注入
- React + Mobx構建React-CnodeReact
- 使用 React Hooks + Context 打造簡版 ReduxReactHookContextRedux
- [譯] 使用 React 和 ImmutableJS 構建一個拖放佈局構建器ReactJS
- DvaJS構建配置React專案與使用JSReact
- 1. Context – React跨元件訪問資料的利器ContextReact元件
- 1. Context - React跨元件訪問資料的利器ContextReact元件
- Android Note - 使用構建分析工具Android
- 如何使用Webpack工具構建專案Web
- 從工程化角度討論如何快速構建可靠React元件React元件
- React構建元件的方式React元件
- 淺談React元件結構React元件
- 使用 react Context API 的正確姿勢ReactContextAPI
- React的Context的使用方法簡介ReactContext
- [譯] 使用 Recompose 來構建高階元件元件
- IBM 使用 react 構建的開源設計系統IBMReact
- 使用React構建大型應用的最佳實踐React
- React Context那些事ReactContext
- React context基本用法ReactContext
- 重拾React: ContextReactContext
- 構建自定義元件元件
- 使用node.js構建命令列工具Node.js命令列
- 使用Spring Boot 2.0快速構建服務元件Spring Boot元件
- 構建自己的React UI元件庫: 從v0.0.0到 v0.0.1ReactUI元件
- 教你如何使用Springboot注入帶引數的建構函式Spring Boot函式
- React構建個人部落格React