這篇文章主要介紹了React和Redux的代碼分離與動態(tài)導入示例,具有一定借鑒價值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。

代碼分離與動態(tài)導入
對于大型 Web應用程序,代碼組織非常重要。 它有助于創(chuàng)建高性能且易于理解的代碼。 最簡單的策略之一就是代碼分離。 使用像 Webpack 這樣的工具,可以將代碼拆分成更小的部分,它們分為兩個不同的策略,靜態(tài)和動態(tài)。
通過靜態(tài)代碼分離,首先將應用程序的每個不同部分作為給定的入口點。 這允許 Webpack 在構建時將每個入口點拆分為單獨的包。 如果我們知道我們的應用程序的哪些部分將被瀏覽最多,這是完美的。
動態(tài)導入使用的是 Webpack 的 import 方法來加載代碼。由于 import 方法返回一個 promise,所以可以使用async wait 來處理返回結果。
// getComponent.js
async function getComponent() {
const {default: module} = await import('../some-other-file')
const element = document.createElement('p')
element.innerHTML = module.render()
return element
}雖然這是一個很不自然的例子,但是可以看到這是一個多么簡單的方法。通過使用 Webpack 來完成繁重的工作,我們可以將應用程序分成不同的模塊。當用戶點擊應用程序的特定部分時,才加載我們需要的代碼。
如果我們將這種方法與 React 提供給我們的控制結構相結合,我們就可以通過延遲加載來進行代碼分割。這允許我們將代碼的加載延遲到最后一分鐘,從而減少初始頁面加載。
使用 React 處理延遲加載
為了導入我們的模塊,我們需要決定應該使用什么 API。考慮到我們使用 React 來渲染內容,讓我們從這里開始。
下面是一個使用 view 命名空間導出模塊組件的簡單API。
// my-module.js
import * as React from 'react'
export default {
view: () => <p>My Modules View</p>
}現(xiàn)在我們使用導入方法來加載這個文件,我們可以很容易地訪問模塊的 view 組件,例如
async function getComponent() {
const {default} = await import('./my-module')
return React.createElement(default.view)
})然而,我們仍然沒有使用 React 中的方法來延遲加載模塊。通過創(chuàng)建一個 LazyLoadModule 組件來實現(xiàn)這一點。該組件將負責解析和渲染給定模塊的視圖組件。
// 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'))下面是一個線上的示例,其中補充一些異常的處理。
https://codesandbox.io/embed/...
通過使用 React 來處理每個模塊的加載,我們可以在應用程序的任何時間延遲加載組件,這包括嵌套模塊。
使用 Redux
到目前為止,我們已經(jīng)演示了如何動態(tài)加載應用程序的模塊。然而,我們仍然需要在加載時將正確的數(shù)據(jù)輸入到我們的模塊中。
讓我們來看看如何將 redux 存儲連接到模塊。 我們已經(jīng)通過公開每個模塊的視圖組件為每個模塊創(chuàng)建了一個 API。 我們可以通過暴露每個模塊的 reducer 來擴展它。 還需要公開一個名稱,在該名稱下我們的模塊狀態(tài)將存在于應用程序的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)。
但是我們需要先對我們的 store 做更多的工作。我們需要能夠在模塊加載時注冊模塊的 reducer。因此,當我們的模塊 dispatche 一個 action 時,我們的 store 就會更新。我們可以使用 replaceReducer 方法來實現(xiàn)這一點。
首先,我們需要添加兩個額外的方法,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;
}如你所見,代碼本身非常簡單。 我們將兩種新方法添加到我們的 store 中。 然后,這些方法中的每一種都完全取代了我們 store 中的 reducer。
以下是如何創(chuàng)建擴充 store:
import createStore from './store'
const rootReducer = {
foo: fooReducer
}
const store = createStore(rootReducer)
const App = () => (
<Provider store={store}>
...
</Provider>
)接下來,需要更新 LazyLoadModule ,以便它可以在我們的 store 中注冊 reducer 模塊。
我們可以通過 props 獲取 store。這很簡單,但這意味著我們每次都必須檢索我們的 store,這可能會導致 bug。記住這一點,讓 LazyLoadModule 組件為我們獲取 store。
當 react-redux <Provider /> 組件將 store 添加到上下文中時,只需要使用 contextTypes 在LazyLoadModule 中獲取它。
// lazyModule.js
export class LazyLoadModule extends React.component {
...
async componentDidMount() {
...
const {store} = this.context
}
}
LazyLoadModule.contextTypes = {
store: PropTypes.object,
}現(xiàn)在可以從 LazyLoadModule 的任何實例訪問我們的 store。 剩下的唯一部分就是把 reducer 注冊到 store 中。 記住,我們是這樣導出每個模塊:
// my-module.js
export default {
name: 'my-module',
view,
reducers,
}更新 LazyLoadModule 的 componentDidMount和 componentWillUnmount 方法來注冊和注銷每個模塊:
// 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 的動態(tài)導入,我們可以將代碼分離添加到我們的應用程序中。這意味著我們的應用程序的每個部分都可以注冊自己的 components 和 reducers,這些 components 和 reducers將按需加載。此外,我們還減少了包的大小和加載時間,這意味著每個模塊都可以看作是一個單獨的應用程序。
感謝你能夠認真閱讀完這篇文章,希望小編分享React和Redux的代碼分離與動態(tài)導入示例內容對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,遇到問題就找創(chuàng)新互聯(lián),詳細的解決方法等著你來學習!
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。
新聞標題:React和Redux的代碼分離與動態(tài)導入示例-創(chuàng)新互聯(lián)
文章源于:http://chinadenli.net/article8/ddpdip.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設計、企業(yè)建站、電子商務、網(wǎng)站收錄、自適應網(wǎng)站、微信小程序
聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)