2017-10-20 45 views
4

我知道混合jQuery和ReactJS是不可取的,因爲ReactJS沒有意識到由jQuery所做的任何DOM修改。但是,如果只使用jQuery來查詢DOM並輕鬆方便地查找節點,同時將所有DOM編輯留給ReactJS。除了jQuery是一個大型圖書館之外,還有其他的缺點嗎?React的jQuery選擇器可以嗎?

一個示例用例設置事件偵聽器,只要下拉菜單組件安裝時檢查用戶是否在菜單的任何地方點擊,以便菜單可以關閉。 jQuery .parents()方法是檢查點擊目標是否是菜單容器元素的子項的非常方便的方法。在ReactJSvanilla JavaScript有沒有簡單的方法來做到這一點?

下面是這個例子的代碼示例:

handleClick = e => { 
    const element = $(e.target) 
    if(!(element.parents('.menu').length || element.hasClass('menu'))) { 
    this.setState({ menuOpen: false }) 
    } 
} 

componentWillUpdate (nextProps, nextState) { 
    if(nextState.menuOpen && !this.state.menuOpen) { 
    document.addEventListener('click', this.handleClick, false) 
    } else if (!nextState.menuOpen && this.state.menuOpen) { 
    document.removeEventListener('click', this.handleClick, false) 
    } 
} 
+1

如果你只想要jQuery的選擇器引擎,請使用[Sizzle](https://sizzlejs.com/)或[Zepto](http://zeptojs.com/)來查看。如果您不擔心向後兼容較舊的非常規瀏覽器,請嘗試此解決方案(https://stackoverflow.com/questions/12980877/parents-without-jquery-or-queryselectorall-for-parents)。 – Terry

+0

結帳https://sizzlejs.com/ –

回答

-1

我是在說你的問題糾正歸結爲:這是OK查詢瀏覽器的DOM爲將要使用的信息作出反應? 由於虛擬DOM總是與瀏覽器DOM同步,因此在瀏覽器DOM中執行只讀查找肯定不會壞。事實上,如果您想添加交互性或用戶事件處理,您有時需要在瀏覽器DOM上執行此操作,而不是虛擬DOM。

然後至於要使用哪個庫:除了jQuery,還有更輕的選項,如minifiedjs。

+0

是的,這是正確的,我正在檢查是否有任何缺陷使用類似jQuery的庫進行瀏覽器DOM查找。你的建議是沒有任何主要的,如果有的話,所以沒關係。我會等着看有沒有人能拿出任何其他的東西,否則我會把你的標記作爲答案。謝謝! –

+0

這裏需要注意的一點是,React已經有一個[API訪問](https://reactjs.org/docs/react-dom.html)DOM,您應該比較喜歡jQuery。 –

1

是的,我會說在React中使用jQuery有缺點。

的VDOM版本比較算法會感到困惑

這是一個你提到的。是的,如果您只使用read-only屬性,那麼效果會很好,但除非您將目標鎖定爲舊版瀏覽器,否則document.querySelector之類的內容重量更輕。

你要引入的每一個依賴,特別是像圖書館那樣大的一個,應該仔細審查。詳情請參閱the website obesity epedemic。我們將在下一個例子中看到,「我只會用它來閱讀並讓React去做其餘的事情」的想法會給你的代碼增加一個很大的混淆層,如下所示。

你放棄的方式做出反應

在我看來,更大的問題是放棄作出反應的方式。用一句話來描述React,我會說:

React是一個基於組件的庫,用於生成從state輸入派生的HTML,CSS和JavaScript功能。

比方說,我有一個簡單的UserProfile組件。此組件將有一些數據關於用戶,包括一個開關以接收推送通知或不:

// Please note this is simplified pseudo-code, and will likely not work 
class UserProfile extends Component { 
    state = { 
    name: 'Bob', 
    profilePic: 'someurl.com/profile-pic', 
    isReceivingNotifications: false 
    } 

    updateReceivingNotifications =() => { 
    this.setState({ isReceivingNotifications: !this.state.isReceivingNotifications }) 
    } 

    render() { 
    const { name, profilePic, isReceivingNotifcations } = this.state; 
    return (
     <div> 
     <h2>{name}</h2> 
     <img src={profilePic} /> 
     <input type="checkbox" checked={isReceivingNotifications} onChange={this.updateReceivingNotifications} /> 
     </div> 
    ); 
    } 
} 

簡單,部件呈現從組件的狀態的。如果isReceivingNotifcations爲true,則複選框將被選中。

讓我們看看所提出的設計模式,這同例如:

class UserProfile extends Component { 
    state = { 
    name: 'Bob', 
    profilePic: 'someurl.com/profile-pic', 
    isReceivingNotifications: false 
    } 

    componentDidMount() { 
    const checkBox = document.getElementById('my-checkbox'); 
    const that = this; 
    // Use a regular function to bind the this context to the checkbox instead of component 
    checkBox.addEventListener('change', function() { 
     if (this.checked) { 
     that.setState({ isReceivingNotifcations: true }); 
     } else { 
     that.setState({ isReceivingNotifcations: false }); 
     } 
    }); 
    } 

    render() { 
    const { name, profilePic, isReceivingNotifcations } = this.state; 
    return (
     <div> 
     <h2>{name}</h2> 
     <img src={profilePic} /> 
     <input 
      type="checkbox" 
      checked={isReceivingNotifications} 
      id="my-checkbox" 
      /> 
     </div> 
    ); 
    } 
} 

首先是乾淨多了,無論你如何使用jQuery或任何DOM操作庫,你會使用這個格式。

這是一個人爲的例子,但每次我在現實生活中看到這個版本的時候,都是一團糟。

最後,爲什麼?

只需要一點時間並學習React設計模式。我建議。 jQuery應該是最後的手段,因爲你使用React是出於我假設的原因。

有一個例外,這是jQuery的庫您使用陣營

在這種情況下,你有超過重寫庫中的其他沒有其他選擇。如this article中突出顯示的那樣,您應該編寫一個包裝組件來使其符合React。

+0

當然,對於所有用戶交互都包含在該組件中的組件,DOM查詢是不必要的。但是如果你需要一個組件來發現在它之外發生的點擊呢?您可以找到HOC,檢查點擊是否發生在外部,但他們可能在內部使用DOM查詢。也許不是JQuery,而是一個DOM查詢。而且更重要的是,如果要求更加複雜呢?如果我需要知道點擊是否發生在當前某個特定組件之外?反應的實現將非常複雜 –

+0

我會說這是使用較不常見的場景來證明一個更常見的場景。不常見的情況是組件外的組件操作(模塊,菜單等)。現在,我們有[門戶](https://reactjs.org/docs/portals.html)來處理這種確切的情況。 –

相關問題