這篇文章主要介紹了React和Redux的代碼分離與動(dòng)態(tài)導(dǎo)入示例,具有一定借鑒價(jià)值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡(jiǎn)單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊(cè)、網(wǎng)絡(luò)空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、烏什網(wǎng)站維護(hù)、網(wǎng)站推廣。
代碼分離與動(dòng)態(tài)導(dǎo)入
對(duì)于大型 Web應(yīng)用程序,代碼組織非常重要。 它有助于創(chuàng)建高性能且易于理解的代碼。 最簡(jiǎn)單的策略之一就是代碼分離。 使用像 Webpack 這樣的工具,可以將代碼拆分成更小的部分,它們分為兩個(gè)不同的策略,靜態(tài)和動(dòng)態(tài)。
通過靜態(tài)代碼分離,首先將應(yīng)用程序的每個(gè)不同部分作為給定的入口點(diǎn)。 這允許 Webpack 在構(gòu)建時(shí)將每個(gè)入口點(diǎn)拆分為單獨(dú)的包。 如果我們知道我們的應(yīng)用程序的哪些部分將被瀏覽最多,這是完美的。
動(dòng)態(tài)導(dǎo)入使用的是 Webpack 的 import 方法來加載代碼。由于 import 方法返回一個(gè) promise,所以可以使用async wait 來處理返回結(jié)果。
// getComponent.js async function getComponent() { const {default: module} = await import('../some-other-file') const element = document.createElement('p') element.innerHTML = module.render() return element }
雖然這是一個(gè)很不自然的例子,但是可以看到這是一個(gè)多么簡(jiǎn)單的方法。通過使用 Webpack 來完成繁重的工作,我們可以將應(yīng)用程序分成不同的模塊。當(dāng)用戶點(diǎn)擊應(yīng)用程序的特定部分時(shí),才加載我們需要的代碼。
如果我們將這種方法與 React 提供給我們的控制結(jié)構(gòu)相結(jié)合,我們就可以通過延遲加載來進(jìn)行代碼分割。這允許我們將代碼的加載延遲到最后一分鐘,從而減少初始頁面加載。
使用 React 處理延遲加載
為了導(dǎo)入我們的模塊,我們需要決定應(yīng)該使用什么 API。考慮到我們使用 React 來渲染內(nèi)容,讓我們從這里開始。
下面是一個(gè)使用 view 命名空間導(dǎo)出模塊組件的簡(jiǎn)單API。
// my-module.js import * as React from 'react' export default { view: () => <p>My Modules View</p> }
現(xiàn)在我們使用導(dǎo)入方法來加載這個(gè)文件,我們可以很容易地訪問模塊的 view 組件,例如
async function getComponent() { const {default} = await import('./my-module') return React.createElement(default.view) })
然而,我們?nèi)匀粵]有使用 React 中的方法來延遲加載模塊。通過創(chuàng)建一個(gè) LazyLoadModule 組件來實(shí)現(xiàn)這一點(diǎn)。該組件將負(fù)責(zé)解析和渲染給定模塊的視圖組件。
// lazyModule.js import * as React from "react"; export class LazyLoadModule extends React.Component { constructor(props) { super(props); this.state = { module: null }; } // after the initial render, wait for module to load async componentDidMount() { const { resolve } = this.props; const { default: module } = await resolve(); this.setState({ module }); } render() { const { module } = this.state; if (!module) return <p>Loading module...</p>; if (module.view) return React.createElement(module.view); } }
以下是使用 LazyLoadModule組件來加載模塊的視圖方式:
// my-app.js import {LazyLoadModule} from './LazyLoadModule' const MyApp = () => ( <p className='App'> <h2>Hello</h2> <LazyLoadModule resolve={() => import('./modules/my-module')} /> </p> ) ReactDOM.render(<MyApp />, document.getElementById('root'))
下面是一個(gè)線上的示例,其中補(bǔ)充一些異常的處理。
https://codesandbox.io/embed/...
通過使用 React 來處理每個(gè)模塊的加載,我們可以在應(yīng)用程序的任何時(shí)間延遲加載組件,這包括嵌套模塊。
使用 Redux
到目前為止,我們已經(jīng)演示了如何動(dòng)態(tài)加載應(yīng)用程序的模塊。然而,我們?nèi)匀恍枰诩虞d時(shí)將正確的數(shù)據(jù)輸入到我們的模塊中。
讓我們來看看如何將 redux 存儲(chǔ)連接到模塊。 我們已經(jīng)通過公開每個(gè)模塊的視圖組件為每個(gè)模塊創(chuàng)建了一個(gè) API。 我們可以通過暴露每個(gè)模塊的 reducer 來擴(kuò)展它。 還需要公開一個(gè)名稱,在該名稱下我們的模塊狀態(tài)將存在于應(yīng)用程序的store 中。
// my-module.js import * as React from 'react' import {connect} from 'react-redux' const mapStateToProps = (state) => ({ foo: state['my-module'].foo, }) const view = connect(mapStateToProps)(({foo}) => <p>{foo}</p>) const fooReducer = (state = 'Some Stuff') => { return state } const reducers = { 'foo': fooReducer, } export default { name: 'my-module', view, reducers, }
上面的例子演示了我們的模塊如何獲得它需要渲染的狀態(tài)。
但是我們需要先對(duì)我們的 store 做更多的工作。我們需要能夠在模塊加載時(shí)注冊(cè)模塊的 reducer。因此,當(dāng)我們的模塊 dispatche
一個(gè) action
時(shí),我們的 store
就會(huì)更新。我們可以使用 replaceReducer 方法來實(shí)現(xiàn)這一點(diǎn)。
首先,我們需要添加兩個(gè)額外的方法,registerDynamicModule和 unregisterDynamicModule到我們的 store 中。
// store.js import * as redux form 'redux' const { createStore, combineReducers } = redux // export our createStore function export default reducerMap => { const injectAsyncReducers = (store, name, reducers) => { // add our new reducers under the name we provide store.asyncReducers[name] = combineReducers(reducers); // replace all of the reducers in the store, including our new ones store.replaceReducer( combineReducers({ ...reducerMap, ...store.asyncReducers }) ); }; // create the initial store using the initial reducers that passed in const store = createStore(combineReducers(reducerMap)); // create a namespace that will later be filled with new reducers store.asyncReducers = {}; // add the method that will allow us to add new reducers under a given namespace store.registerDynamicModule = ({ name, reducers }) => { console.info(`Registering module reducers for ${name}`); injectAsyncReducers(store, name, reducers); }; // add a method to unhook our reducers. This stops our reducer state from updating any more. store.unRegisterDynamicModule = name => { console.info(`Unregistering module reducers for ${name}`); const noopReducer = (state = {}) => state; injectAsyncReducers(store, name, noopReducer); }; // return our augmented store object return store; }
如你所見,代碼本身非常簡(jiǎn)單。 我們將兩種新方法添加到我們的 store
中。 然后,這些方法中的每一種都完全取代了我們 store中的 reducer。
以下是如何創(chuàng)建擴(kuò)充 store
:
import createStore from './store' const rootReducer = { foo: fooReducer } const store = createStore(rootReducer) const App = () => ( <Provider store={store}> ... </Provider> )
接下來,需要更新 LazyLoadModule,以便它可以在我們的 store中注冊(cè) reducer模塊。
我們可以通過 props
獲取 store
。這很簡(jiǎn)單,但這意味著我們每次都必須檢索我們的 store
,這可能會(huì)導(dǎo)致 bug。記住這一點(diǎn),讓 LazyLoadModule組件為我們獲取 store。
當(dāng) react-redux <Provider />組件將 store添加到上下文中時(shí),只需要使用 contextTypes在LazyLoadModule中獲取它。
// lazyModule.js export class LazyLoadModule extends React.component { ... async componentDidMount() { ... const {store} = this.context } } LazyLoadModule.contextTypes = { store: PropTypes.object, }
現(xiàn)在可以從 LazyLoadModule的任何實(shí)例訪問我們的 store。 剩下的唯一部分就是把 reducer注冊(cè)到 store中。 記住,我們是這樣導(dǎo)出每個(gè)模塊:
// my-module.js export default { name: 'my-module', view, reducers, }
更新 LazyLoadModule的 componentDidMount和 componentWillUnmount方法來注冊(cè)和注銷每個(gè)模塊:
// lazyModule.js export class LazyLoadModule extends React.component { ... async componentDidMount() { ... const { resolve } = this.props; const { default: module } = await resolve(); const { name, reducers } = module; const { store } = this.context; if (name && store && reducers) store.registerDynamicModule({ name, reducers }); this.setState({ module }); } ... componentWillUnmount() { const { module } = this.state; const { store } = this.context; const { name } = module; if (store && name) store.unRegisterDynamicModule(name); } }
通過使用 Webpack 的動(dòng)態(tài)導(dǎo)入,我們可以將代碼分離添加到我們的應(yīng)用程序中。這意味著我們的應(yīng)用程序的每個(gè)部分都可以注冊(cè)自己的 components 和 reducers,這些 components 和 reducers將按需加載。此外,我們還減少了包的大小和加載時(shí)間,這意味著每個(gè)模塊都可以看作是一個(gè)單獨(dú)的應(yīng)用程序。
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享React和Redux的代碼分離與動(dòng)態(tài)導(dǎo)入示例內(nèi)容對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,遇到問題就找創(chuàng)新互聯(lián),詳細(xì)的解決方法等著你來學(xué)習(xí)!
當(dāng)前題目:React和Redux的代碼分離與動(dòng)態(tài)導(dǎo)入示例
網(wǎng)頁路徑:http://m.rwnh.cn/article28/pcddcp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)、App開發(fā)、網(wǎng)站改版、網(wǎng)站制作、網(wǎng)站維護(hù)、域名注冊(cè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)