亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

和其他庫(kù)(jquery,backbone)一起使用react

ckllj / 3392人閱讀

摘要:也就是說(shuō),只要一發(fā)生事件。和其他的庫(kù)共用由于方法的靈活性使得可以被嵌入到其他的應(yīng)用中。事實(shí)上,這就是在被使用的方式。在應(yīng)用中使用的層在組件中消費(fèi)中和最簡(jiǎn)單的方法是監(jiān)聽各種事件并手動(dòng)進(jìn)行強(qiáng)制更新。并且使用組件來(lái)渲染各個(gè)項(xiàng)。

注:由于譯者水平有限,難免會(huì)出現(xiàn)錯(cuò)誤,希望大家能指出,謝謝。

react 可以被用在任何的web 應(yīng)用中。它可以被嵌入到其他的應(yīng)用中,要是你小心一點(diǎn),其他的應(yīng)用也能被嵌入到react中。這篇文章將會(huì)從一些常用的使用場(chǎng)景入手,重點(diǎn)會(huì)關(guān)注與jQuery 和backbone 的交互。但是里面的思想在我們和其他庫(kù)交互時(shí)都是可以被參考的。

和操縱DOM的插件的交互

react 感知不到它管理之外的dom 的變化。react的更新是取決于其內(nèi)部的表現(xiàn),如果同樣的DOM節(jié)點(diǎn)被其他可操作dom節(jié)點(diǎn)的插件更改了,react內(nèi)部狀態(tài)就會(huì)變的很混亂并且無(wú)法恢復(fù)了。

這并不意味著react 無(wú)法和那些操縱DOM 的插件一起共用,你只需要更加清楚每個(gè)插件做了什么。

最簡(jiǎn)單的避免這種沖突發(fā)生的方式是阻止react 組件的更新。你可以通過(guò)渲染一個(gè)react 沒(méi)有必要去更新的元素,比如一個(gè)空的

如何處理這種問(wèn)題

為了更好的闡述這個(gè)問(wèn)題,讓我們來(lái)對(duì)一個(gè)一般的jquery 插件添加一個(gè)wrapper。

首先,我們?cè)谶@個(gè)節(jié)點(diǎn)上添加一個(gè)ref屬性。在componentDidMount 方法里,我們通過(guò)獲取這個(gè)節(jié)點(diǎn)的引用,將它傳給jquery 插件。

為了避免react 在渲染期間對(duì)這個(gè)節(jié)點(diǎn)進(jìn)行改變, 我們?cè)趓ender() 方法里面返回了一個(gè)空的

.這個(gè)空的節(jié)點(diǎn)沒(méi)有任何的屬性或子節(jié)點(diǎn),所以React 不會(huì)對(duì)該節(jié)點(diǎn)進(jìn)行更新,這個(gè)節(jié)點(diǎn)的控制權(quán)完全在jQuery插件上。這樣就不會(huì)出現(xiàn)react 和jquery 插件都操作同樣的dom 的問(wèn)題了。

class SomePlugin extends React.Component {
  componentDidMount() {
    this.$el = $(this.el);
    this.$el.somePlugin();
  }

  componentWillUnmount() {
    this.$el.somePlugin("destroy");
  }

  render() {
    return 
this.el = el} />; } }

需要注意的是,我們定義了componentDidMount() 和componentWillUnmount() 兩個(gè)生命周期的鉤子函數(shù)。這是因?yàn)榇蠖鄶?shù)的jQuery插件都將事件監(jiān)聽綁定在DOM上,所以在componentWillUnmount 中一定要移除事件監(jiān)聽。如果這個(gè)插件沒(méi)有提供移除的方法,那你就要自己寫了。一定要記得移除插件所注冊(cè)的事件,否則可能會(huì)出現(xiàn)內(nèi)存泄露。

和jQuery 的選擇器插件共用

為了對(duì)這些概念有更深入的了解,我們?yōu)镃hosen 插件寫了一個(gè)小型的wrapper。Chosen 插件的參數(shù)是一個(gè) 節(jié)點(diǎn)應(yīng)用了該組件。它會(huì)讀取原始DOM節(jié)點(diǎn)的屬性,使用內(nèi)聯(lián)樣式隱藏它。并且使用自己的展示方式在

class Chosen extends React.Component {
  render() {
    return (
      
); } }

需要注意的是,我們?cè)?select>標(biāo)簽外加了一個(gè)

標(biāo)簽。這很有必要,因?yàn)槲覀兒罄m(xù)會(huì)在節(jié)點(diǎn)的引用來(lái)初始化Chosen.并且在componentDidUnmount 里面銷毀它。

componentDidMount() {
  this.$el = $(this.el);
  this.$el.chosen();
}

componentWillUnmount() {
  this.$el.chosen("destroy");
}

記住,react 不會(huì)對(duì)this.el 字段賦予任何特殊的含義。除非你之前在render方法里面對(duì)它進(jìn)行賦值。

上 訂閱了jQuery 的change事件。

我們不會(huì)直接的將this.props.onChange傳給Chosen. 因?yàn)榻M件的屬性可能會(huì)一直改變,而且這里還包含著事件的處理。因?yàn)?,我們聲明了一個(gè)handleChange方法來(lái)調(diào)用this.props.onChange.并且為它訂閱了jQuery的change事件中。也就是說(shuō),只要一發(fā)生change 事件。就會(huì)自動(dòng)執(zhí)行handleChange 方法。

componentDidMount() {
  this.$el = $(this.el);
  this.$el.chosen();

  this.handleChange = this.handleChange.bind(this);
  this.$el.on("change", this.handleChange);
}

componentWillUnmount() {
  this.$el.off("change", this.handleChange);
  this.$el.chosen("destroy");
}

handleChange(e) {
  this.props.onChange(e.target.value);
}

最后,我們還有一件事要做。在React 中,由于屬性是可以一直改變的。例如,組件能夠獲取不同的children 如果父組件狀態(tài)改變的話。這意味著在交互過(guò)程中,很重要的一點(diǎn)是,當(dāng)屬性改變時(shí),我們需要手動(dòng)的控制DOM的更新,不再需要react 來(lái)為我們管理DOM節(jié)點(diǎn)了。

Chosen 的文檔建議我們使用jQuery 的trigger() 方法來(lái)通知原始DOM元素的變化。我們將使React重點(diǎn)關(guān)注在 節(jié)點(diǎn)改變的時(shí)候,Chosen 就會(huì)知道需要更新DOM元素了。

class Chosen extends React.Component {
    componentDidMount() {
        this.$el = $(this.el);
        this.$el.chosen();
        this.handleChange = this.handleChange.bind(this);
        this.$(el).on("change", this.handleChange);
    }
    
    componentDidUpdate(prevProps) {
        if (prevProps.children !== this.props.children) {
            this.$el.trigger("chosen:updated");
        }
    }
    
    componentWillUnmount() {
        this.$el.off("change", this.handleChange);
        this.$el.chosen("destory");
    }
    
    handleChange(e) {
        this.props.onChange(e.target.value);
    }
    
    render() {
        return (
            
); } }
和其他的View 庫(kù)共用

由于ReactDOM.render()方法的靈活性使得React可以被嵌入到其他的應(yīng)用中。

由于React 通常被用來(lái)將一個(gè)React 節(jié)點(diǎn)渲染到某個(gè)DOM元素中,而且ReactDOM.render()可以被UI的各個(gè)獨(dú)立的部分多次調(diào)用,小到一個(gè)按鈕,大到一個(gè)app。

事實(shí)上,這就是React 在Facebook 被使用的方式。這使得我們可以在React 中一塊一塊的開發(fā)一個(gè)應(yīng)用,并且可以把它整合在現(xiàn)有的服務(wù)器渲染的模版中或者其他的客戶端代碼中。

使用React替換基于字符串的渲染

在一些老的web 應(yīng)用,一種常見(jiàn)的方式是寫一大段DOM結(jié)構(gòu)作為字符串,然后使用$el.html(htmlString) 的方式插入到DOM節(jié)點(diǎn)中。如果你的代碼庫(kù)中有類似的場(chǎng)景,那么推薦你使用react。你只需要將使用字符串渲染的部分改成react 組件就可以了。
下面是一個(gè)jQuery 的實(shí)現(xiàn)

$("#container").html("");
$("#btn").click(function() {
  alert("Hello!");
});

改成react 的實(shí)現(xiàn)

function Button() {
  return ;
}

ReactDOM.render(
  

接下來(lái),你可以將更多的業(yè)務(wù)邏輯移到react組件中去并且采用更多react 實(shí)踐方式。例如,組件最好不要依賴id,因?yàn)橥瑯拥慕M件可能會(huì)被渲染多次。而且,我們推薦使用react 的事件系統(tǒng),直接在組件; } function HelloButton() { function handleClick() { alert("Hello!"); } return

你可以有很多這樣獨(dú)立的組件,并且使用ReactDOM.render()方法將他們渲染到不同的DOM節(jié)點(diǎn)中。慢慢的,你在app 中使用越來(lái)越多的react 技術(shù),你就可以將這些獨(dú)立的組件整合成更大的組件。同時(shí),將一些ReactDOM.render() 的調(diào)用移動(dòng)到不同的層級(jí)中。

將React 嵌入到Backbone 的視圖中

Backbone 的視圖就是典型的使用HTML 字符串,或者使用一些字符串模版函數(shù)來(lái)生成這樣的字符串,然后將之作為DOM元素的內(nèi)容。這種處理方式,也能被替換為使用React 組件渲染的方式。

下面,我們將會(huì)創(chuàng)建一個(gè)Backbone 的視圖ParagraphView. 我們會(huì)通過(guò)渲染一個(gè)React 組件,然后使用Backbone 提供的(this.el)方式將它插入到DOM元素中的方式來(lái)重寫B(tài)ackbone 的render() 方法. 當(dāng)然,我們也會(huì)使用ReactDOM.render()方法.

function Paragraph(props) {
  return 

{props.text}

; } const ParagraphView = Backbone.View.extend({ render() { const text = this.model.get("text"); ReactDOM.render(, this.el); return this; }, remove() { ReactDOM.unmountComponentAtNode(this.el); Backbone.View.prototype.remove.call(this); } });

很重要的一件事是,我們必須在remove方法中調(diào)用 ReactDOM.unmountComponentAtNode() 方法來(lái)解除通過(guò)react 注冊(cè)的事件和一些其他的資源。

當(dāng)一個(gè)組件從react樹中移除時(shí),一些清理工作會(huì)被自動(dòng)執(zhí)行。但是因?yàn)槲覀兪謩?dòng)的移除了整個(gè)樹,所以我們必須要調(diào)用這個(gè)方法來(lái)進(jìn)行清理工作。

和Model 層進(jìn)行交互

通常我們推薦使用單向數(shù)據(jù)流比如React state, Flux 或者Redux來(lái)管理react 應(yīng)用。其實(shí),react 也能使用一些其他框架或者庫(kù)的Model 層來(lái)進(jìn)行管理。

在react 應(yīng)用中使用Backbone 的model層

在React 組件中消費(fèi)Backbone中model和collections 最簡(jiǎn)單的方法是監(jiān)聽各種change 事件并手動(dòng)進(jìn)行強(qiáng)制更新。

渲染models 的組件會(huì)監(jiān)聽 "change"事件,渲染collections 的組件會(huì)監(jiān)聽‘a(chǎn)dd’和‘remove’事件。然后,調(diào)用this.forceUpdate() 來(lái)使用新數(shù)據(jù)重新渲染組件。

下面的例子中,List 組件會(huì)渲染一個(gè)Backbone 容器。并且使用Item 組件來(lái)渲染各個(gè)項(xiàng)。

class Item extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange() {
    this.forceUpdate();
  }

  componentDidMount() {
    this.props.model.on("change", this.handleChange);
  }

  componentWillUnmount() {
    this.props.model.off("change", this.handleChange);
  }

  render() {
    return 
  • {this.props.model.get("text")}
  • ; } } class List extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange() { this.forceUpdate(); } componentDidMount() { this.props.collection.on("add", "remove", this.handleChange); } componentWillUnmount() { this.props.collection.off("add", "remove", this.handleChange); } render() { return (
      {this.props.collection.map(model => ( ))}
    ); } }
    從Backbone 的Models 中提取數(shù)據(jù)

    上述的處理方式要求你的React 組件能夠感知到Backbone 的Models 和 Collections .如果你后續(xù)要整合其他的數(shù)據(jù)管理方案,你可能需要更多關(guān)注Backbone 的實(shí)現(xiàn)細(xì)節(jié)了。

    解決這個(gè)問(wèn)題的一個(gè)方法是,當(dāng)model 的屬性改變時(shí),將它提取為普通的數(shù)據(jù),并將這段邏輯保存在一個(gè)多帶帶的地方。下面演示的是一個(gè)高階組件,這個(gè)組件將Backbone 的model層的屬性轉(zhuǎn)換為state,然后把數(shù)據(jù)傳遞給被包裹的組件。

    通過(guò)這種方式,只有這個(gè)高階組件需要知道Backbone Models的內(nèi)部細(xì)節(jié)信息,大部分的組件對(duì)Backbone 都是透明的。

    下面的例子中,我們會(huì)對(duì)Model 的屬性進(jìn)行一份拷貝來(lái)作為初始state。我們注冊(cè)了change 事件(在unmounting 中取消注冊(cè)),當(dāng)監(jiān)聽到change事件的時(shí)候,我們用model 當(dāng)前的屬性來(lái)更新state。最后,我們要確保,如果model 的屬性自己改變的話,我們不要忘記從老的model上取消訂閱,然后訂閱新的model。

    注意,這個(gè)例子不是為了說(shuō)明和Backbone 一起協(xié)作的細(xì)節(jié),你更應(yīng)該通過(guò)這個(gè)例子了解到處理這類問(wèn)題的一種通用的方式。

    function connectToBackboneModel(WrappedComponent) {
      return class BackboneComponent extends React.Component {
        constructor(props) {
          super(props);
          this.state = Object.assign({}, props.model.attributes);
          this.handleChange = this.handleChange.bind(this);
        }
    
        componentDidMount() {
          this.props.model.on("change", this.handleChange);
        }
    
        componentWillReceiveProps(nextProps) {
          this.setState(Object.assign({}, nextProps.model.attributes));
          if (nextProps.model !== this.props.model) {
            this.props.model.off("change", this.handleChange);
            nextProps.model.on("change", this.handleChange);
          }
        }
    
        componentWillUnmount() {
          this.props.model.off("change", this.handleChange);
        }
    
        handleChange(model) {
          this.setState(model.changedAttributes());
        }
    
        render() {
          const propsExceptModel = Object.assign({}, this.props);
          delete propsExceptModel.model;
          return ;
        }
      }
    }

    為了闡述如何來(lái)使用它,我們會(huì)將一個(gè)react組件NameInput 和Backbone 的model 層結(jié)合起來(lái)使用,并且每次輸入發(fā)生改變時(shí),就會(huì)更新firstName 屬性。

    function NameInput(props) {
      return (
        


    My name is {props.firstName}.

    ); } const BackboneNameInput = connectToBackboneModel(NameInput); function Example(props) { function handleChange(e) { model.set("firstName", e.target.value); } return ( ); } const model = new Backbone.Model({ firstName: "Frodo" }); ReactDOM.render( , document.getElementById("root") );

    這些處理技巧不僅限于Backbone. 你也可以使用React 和其他的model 庫(kù)進(jìn)行整合,通過(guò)在生命周期中訂閱它的變化,并且,選擇性的,將數(shù)據(jù)復(fù)制到react 的state中。

    文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

    轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/88570.html

    相關(guān)文章

    • 2017年前端流行的數(shù)百個(gè)javascript庫(kù),你會(huì)幾個(gè)?

      摘要:有數(shù)百個(gè)免費(fèi)的庫(kù)出來(lái),為應(yīng)用程序選擇正確的框架變得非常困難。是流行的驅(qū)動(dòng)技術(shù)之一,由于年創(chuàng)建。在這三個(gè)塊中,有幾個(gè)暴露低層接口的綁定。反應(yīng)由,和許多開發(fā)人員和個(gè)人的社區(qū)維護(hù)。誕生于年,是一個(gè)輕量級(jí)的框架。 有數(shù)百個(gè)免費(fèi)的JS庫(kù)出來(lái),為應(yīng)用程序選擇正確的JavaScript框架變得非常困難。一些開發(fā)商最終會(huì)拋棄,而其他開發(fā)者則迅速發(fā)展,并得到廣泛采用。許多開發(fā)人員只知道像jQuery和R...

      CoXie 評(píng)論0 收藏0
    • 《高性能JavaScript》(讀書筆記)

      摘要:加載的模塊會(huì)以參數(shù)形式傳入該函數(shù),從而在回調(diào)函數(shù)內(nèi)部就可以使用這些模塊。異步加載,和,瀏覽器不會(huì)失去響應(yīng)它指定的回調(diào)函數(shù),只有前面的模塊都加載成功后,才會(huì)運(yùn)行,解決了依賴性的問(wèn)題。插件,可以讓回調(diào)函數(shù)在頁(yè)面結(jié)構(gòu)加載完成后再運(yùn)行。 這次主要是對(duì)《高性能JavaScript》一書的讀書筆記,記錄下自己之前沒(méi)有注意到或者需要引起重視的地方 第一章 加載和執(zhí)行 js代碼在執(zhí)行過(guò)程中會(huì)阻塞瀏覽...

      moven_j 評(píng)論0 收藏0
    • 前端MVC手腳架

      摘要:前端手腳架項(xiàng)目地址構(gòu)建工具基礎(chǔ)庫(kù)這個(gè)項(xiàng)目類似,主要是用于記錄,以及考察現(xiàn)在比較流行的前端庫(kù)在實(shí)際開發(fā)當(dāng)中的開發(fā)體驗(yàn)。其中,構(gòu)建都是基于,支持語(yǔ)法但在中,只用到的模塊管理與析構(gòu)語(yǔ)法。 前端MVC手腳架 項(xiàng)目地址 https://github.com/lizzz0523/mvc-mode-seed 1.構(gòu)建工具 [x] webpack [x] babel-loader [x] babel...

      pekonchan 評(píng)論0 收藏0
    • 基于 Backbone + node 的個(gè)人簡(jiǎn)歷生成器(個(gè)人學(xué)習(xí)總結(jié))

      摘要:應(yīng)用的功能這個(gè)應(yīng)用是一個(gè)個(gè)人簡(jiǎn)歷生成器。比較好的教程有這一個(gè)。這樣的命名污染問(wèn)題自然顯而易見(jiàn)。而且發(fā)出多次請(qǐng)求也會(huì)影響性能。明顯不利于維護(hù)。然而我希望能夠不發(fā)生變化,因?yàn)槭窃谖募那疤嵯碌臉?biāo)簽頁(yè),不能換一個(gè)標(biāo)簽就重建一個(gè)。 為什么學(xué)習(xí)backbone?這是個(gè)好問(wèn)題。在這個(gè)前端框架爆炸的年代,比起backbone,對(duì)開發(fā)來(lái)說(shuō)有更多更好的選擇,react,vue,angular等等。但這些...

      lansheng228 評(píng)論0 收藏0
    • 2017年前端框架、類庫(kù)、工具大比拼

      摘要:相比于開發(fā)人員的數(shù)量,目前框架類庫(kù)和工具的數(shù)量似乎更多一些。本文將會(huì)討論目前最為流行的客戶端框架類庫(kù)和工具以及它們之間的基本差異。典型的類庫(kù)包括字符串處理日期元素事件動(dòng)畫網(wǎng)絡(luò)請(qǐng)求等功能。所以不需要明確的區(qū)分類庫(kù)框架和工具。 相比于JavaScript開發(fā)人員的數(shù)量,目前JavaScript框架、類庫(kù)和工具的數(shù)量似乎更多一些。截至2017年5月,GitHub上的快速搜索顯示,有超過(guò)110...

      Alliot 評(píng)論0 收藏0

    發(fā)表評(píng)論

    0條評(píng)論

    最新活動(dòng)
    閱讀需要支付1元查看
    <