除了dangerouslySetInnerHTML我們還能怎么辦?

使用react開發(fā)前端項目,我們常會遇到需要在一個dom里直接篩入一段純html(后端給的)的需求,比如我們的編輯器,文章的初始內(nèi)容是一段通過ajax獲取的html。當然這么一個常見的需求,react當然幫你想好了解決方案,那就是dangerouslySetInnerHTML,但是就是使用上有點丑陋,需要這樣寫dangerouslySetInnerHTML={{ __html: content }}

dangerouslySetInnerHTML有時候也會顯得有點捉襟,我們看這樣一個需求:我不但需要直接在dom里插入純html,我在插入前需要對這段html的元素做些處理,比如需要在每一個元素里再插入一個元素,或者需要給里面的元素綁定事件。
這種需求用dangerouslySetInnerHTML來實現(xiàn)的話,我們就需要在插入html前對html手動處理下,寫一個原生的方法,遍歷每一個元素并插入我們需要的元素,最后返回一段處理好的新的html,然后每一次變化都重新處理重新設(shè)置和更新整塊html,這樣的弊端有兩個:

  1. 就是對于一個需求我需要實現(xiàn)一個處理dom的工具方法,n個需求我可能需要實現(xiàn)n方法。
  2. 沒有利用到react的局部更新的優(yōu)勢,每次都是整塊更新。

對于需要綁定事件的需求來說,dangerouslySetInnerHTML方式就顯得更加拙劣了。首先我們在 componentDidMount時候,使用findDomNode的方式給指定dom綁定原生事件,或者通過事件代理的方式,給父元素綁定事件,通過target來識別指定元素。這還是在使用react么?這樣弊端也很明顯:

  1. 原生事件機制與react事件機制混用,不易維護、把握不好容易出岔子。
  2. 通過target綁定,有時候并不是這么好判定。

我們使用react的話,肯定是希望:1. 盡量少些原生代碼(寫的話也應該是寫個工具或者lib之類的),2. 充分利用react的優(yōu)勢,3. dom和事件都交給react來管理,不需要另搞一套。

所以我們當時就在想,如果想要實現(xiàn)需求,又不另外搞一套,那就需要把html轉(zhuǎn)成react element,最后通過jsx語法渲染出來,這樣就完全融入到你react整個框架中,很清爽,也很靈活啊。

后來我發(fā)現(xiàn)早有高人寫好了這樣的庫,讓html直接主換成react element(component),比如htmr這個庫。其實這樣的庫實現(xiàn)也很簡單,就是利用React.createElement方法把一個個的dom轉(zhuǎn)成了react element。

這里貼一下怎么使用這個庫吧

import convert from 'htmr';

render() {
    return (
      // react一樣可以玩dom啊
      convert(html).map((reactElement, k) => {
        // 不需要處理的元素就可以直接返回
        if (element.type === 'hr') {
          return element;
        }
        // 需要處理的元素,通過jsx語法展開渲染,方便添加事件和子元素
        return (
                <element.type {...element.props}
                  key={k}
                >
                  {element.props.children}
                  {/* 以下就是 新增加的子元素,并給他綁定了事件  */}
                  <span className={maskItemClass}
                    onClick={this.onMaskItemClickReact}
                    data-index={k}
                  >
                    <em></em>
                  </span>
                </element.type>
              );
      })
    );
}

這樣使用后就完全不需要寫額外的原生代碼,整個dom和事件都交給了react,處理上要靈活許多哈。

標題問的還能怎么辦?其實可以總結(jié)一句話:我們還能把html轉(zhuǎn)成react element并用jsx語法渲染。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容