国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

React 和 Redux 的動態導入

jayzou / 455人閱讀

摘要:動態導入使用的是的方法來加載代碼。使用到目前為止,我們已經演示了如何動態加載應用程序的模塊。還需要公開一個名稱,在該名稱下我們的模塊狀態將存在于應用程序的中。剩下的唯一部分就是把注冊到中。

想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你!

代碼分離與動態導入

對于大型 Web應用程序,代碼組織非常重要。 它有助于創建高性能且易于理解的代碼。 最簡單的策略之一就是代碼分離。 使用像 Webpack 這樣的工具,可以將代碼拆分成更小的部分,它們分為兩個不同的策略,靜態和動態。

通過靜態代碼分離,首先將應用程序的每個不同部分作為給定的入口點。 這允許 Webpack 在構建時將每個入口點拆分為多帶帶的包。 如果我們知道我們的應用程序的哪些部分將被瀏覽最多,這是完美的。

動態導入使用的是 Webpackimport 方法來加載代碼。由于 import 方法返回一個 promise,所以可以使用async wait 來處理返回結果。

// getComponent.js
async function getComponent() {
   const {default: module} = await import("../some-other-file")
   const element = document.createElement("div")
   element.innerHTML = module.render()
   return element
}

雖然這是一個很不自然的例子,但是可以看到這是一個多么簡單的方法。通過使用 Webpack 來完成繁重的工作,我們可以將應用程序分成不同的模塊。當用戶點擊應用程序的特定部分時,才加載我們需要的代碼。

如果我們將這種方法與 React 提供給我們的控制結構相結合,我們就可以通過延遲加載來進行代碼分割。這允許我們將代碼的加載延遲到最后一分鐘,從而減少初始頁面加載。

使用 React 處理延遲加載

為了導入我們的模塊,我們需要決定應該使用什么 API。考慮到我們使用 React 來渲染內容,讓我們從這里開始。

下面是一個使用 view 命名空間導出模塊組件的簡單API。

// my-module.js
import * as React from "react"

export default {
    view: () => 
My Modules View
}

現在我們使用導入方法來加載這個文件,我們可以很容易地訪問模塊的 view 組件,例如

async function getComponent() {
    const {default} = await import("./my-module")
    return React.createElement(default.view)
})

然而,我們仍然沒有使用 React 中的方法來延遲加載模塊。通過創建一個 LazyLoadModule 組件來實現這一點。該組件將負責解析和渲染給定模塊的視圖組件。

// 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 
Loading module...
; if (module.view) return React.createElement(module.view); } }

以下是使用 LazyLoadModule 組件來加載模塊的視圖方式:

// my-app.js

import {LazyLoadModule} from "./LazyLoadModule"

const MyApp = () => (
    

Hello

import("./modules/my-module")} />
) ReactDOM.render(, document.getElementById("root"))

下面是一個線上的示例,其中補充一些異常的處理。

https://codesandbox.io/embed/...

通過使用 React 來處理每個模塊的加載,我們可以在應用程序的任何時間延遲加載組件,這包括嵌套模塊。

使用 Redux

到目前為止,我們已經演示了如何動態加載應用程序的模塊。然而,我們仍然需要在加載時將正確的數據輸入到我們的模塊中。

讓我們來看看如何將 redux 存儲連接到模塊。 我們已經通過公開每個模塊的視圖組件為每個模塊創建了一個 API。 我們可以通過暴露每個模塊的 reducer 來擴展它。 還需要公開一個名稱,在該名稱下我們的模塊狀態將存在于應用程序的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}) => 
{foo}
) const fooReducer = (state = "Some Stuff") => { return state } const reducers = { "foo": fooReducer, } export default { name: "my-module", view, reducers, }

上面的例子演示了我們的模塊如何獲得它需要渲染的狀態。

但是我們需要先對我們的 store 做更多的工作。我們需要能夠在模塊加載時注冊模塊的 reducer。因此,當我們的模塊 dispatche 一個 action 時,我們的 store 就會更新。我們可以使用 replaceReducer 方法來實現這一點。

首先,我們需要添加兩個額外的方法,registerDynamicModuleunregisterDynamicModule 到我們的 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

以下是如何創建擴充 store

import createStore from "./store"

const rootReducer = {
    foo: fooReducer
}

const store = createStore(rootReducer)

const App = () => (
    
        ...
    
)

接下來,需要更新 LazyLoadModule ,以便它可以在我們的 store 中注冊 reducer 模塊。

我們可以通過 props 獲取 store。這很簡單,但這意味著我們每次都必須檢索我們的 store,這可能會導致 bug。記住這一點,讓 LazyLoadModule 組件為我們獲取 store

react-redux 組件將 store 添加到上下文中時,只需要使用 contextTypesLazyLoadModule 中獲取它。

// lazyModule.js 
export class LazyLoadModule extends React.component {
    ...
    async componentDidMount() {
        ...
        const {store} = this.context
    }
}

LazyLoadModule.contextTypes = {
    store: PropTypes.object,
}

現在可以從 LazyLoadModule 的任何實例訪問我們的 store。 剩下的唯一部分就是把 reducer 注冊到 store 中。 記住,我們是這樣導出每個模塊:

// my-module.js
export default {
    name: "my-module",
    view,
    reducers,
}

更新 LazyLoadModulecomponentDidMountcomponentWillUnmount 方法來注冊和注銷每個模塊:

// 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);
    }
}

線上示例如下:
https://codesandbox.io/s/znx1...

總結

通過使用 Webpack 的動態導入,我們可以將代碼分離添加到我們的應用程序中。這意味著我們的應用程序的每個部分都可以注冊自己的 components 和 reducers,這些 components 和 reducers將按需加載。此外,我們還減少了包的大小和加載時間,這意味著每個模塊都可以看作是一個多帶帶的應用程序。

原文:
https://codeburst.io/dynamic-...

你的點贊是我持續分享好東西的動力,歡迎點贊!

交流

干貨系列文章匯總如下,覺得不錯點個Star,歡迎 加群 互相學習。

https://github.com/qq44924588...

我是小智,公眾號「大遷世界」作者,對前端技術保持學習愛好者。我會經常分享自己所學所看的干貨,在進階的路上,共勉!

關注公眾號,后臺回復福利,即可看到福利,你懂的。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/102841.html

相關文章

  • react-redux初級教程,純白話講述redux數據、開發流程整理,redux數據持久化實現

    摘要:日常項目直接使用是完全沒有問題的,可是隨著項目的日益壯大,組件數量的逐漸增長,組件之間的嵌套使得數據的管理越來越繁重。最后數據保存進了中的,頁面也會根據的改變自動更新。 以下文章均為個人近期所學心得,自學react、redux,逐漸找到自己的方向,現將自己的方向方式寫出來,以供大家學習參考,肯定會有不足,歡迎批評指正。 日常項目直接使用react是完全沒有問題的,可是隨著項目的日益壯大...

    gclove 評論0 收藏0
  • React 實踐心得:react-redux 之 connect 方法詳解

    摘要:但這并不是最佳的方式。最佳的方式是使用提供的和方法。也就是說,與的與完全無關。另外,如果使用對做屬性類型檢查,方法和方法為添加的屬性是存在的。注意,的變化不會引起上述過程,默認在組件的生命周期中是固定的。 轉載注: 本文作者是淘寶前端團隊的葉齋。筆者非常喜歡這篇文章,故重新排版并轉載到這里,同時也加入了一些自己的體會。 原文地址:http://taobaofed.org/blog/...

    張春雷 評論0 收藏0
  • 前端最實用書簽(持續更新)

    摘要:前言一直混跡社區突然發現自己收藏了不少好文但是管理起來有點混亂所以將前端主流技術做了一個書簽整理不求最多最全但求最實用。 前言 一直混跡社區,突然發現自己收藏了不少好文但是管理起來有點混亂; 所以將前端主流技術做了一個書簽整理,不求最多最全,但求最實用。 書簽源碼 書簽導入瀏覽器效果截圖showImg(https://segmentfault.com/img/bVbg41b?w=107...

    sshe 評論0 收藏0
  • webpack4 中最新 React全家桶實戰使用配置指南!

    摘要:安裝配置加載器配置配置文件配置支持自定義的預設或插件只有配置了這兩個才能讓生效,單獨的安裝是無意義的。 showImg(https://segmentfault.com/img/bVbjGNY?w=2847&h=1931); 想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你! 最新React全家桶實戰使用配置指南 這篇文檔 是呂小明老師結合以往的項目經驗 加上自己本身...

    Towers 評論0 收藏0

發表評論

0條評論

jayzou

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<