簡體   English   中英

如何將 RxJs 連接到 React 組件

[英]How to connect RxJs to React component

大多數使用 RxJS 觀察按鈕點擊的例子如下:

var button = document.querySelector('button');
Rx.Observable.fromEvent(button, 'click')
  .subscribe(() => console.log('Clicked!'));

這在 React 中可以嗎? 既然有虛擬 DOM,那么像這樣引用真實 DOM 還可以嗎? 重新渲染后會發生什么? 訂閱丟失了嗎?

即他們使用document.querySelector 但是當我編寫我的 render() 方法時,我習慣於<button onClick={...} > 在 React 中推薦的方法是什么? 擺脫 JSX 中的 onClick,向我的按鈕添加一個類/ID,或者可能是一個引用,然后使用上面的樣式?

另外,我應該在任何地方取消訂閱,例如在componentWillUnmount()中嗎? 在這種情況下,我想保留對所有訂閱者(事件偵聽器)的引用? 在這種情況下,這似乎比舊的(回調)方式復雜得多。

對此有什么建議和想法嗎?

我已經考慮了很多 - 我認為@ArtemDevAkk 的答案是一種非常好的方法,但我不確定它是否說明了您打算如何使用數據。 我想提出一種替代方法。 誠然,我為此使用了鈎子,但你可以在老學校的課堂上以類似的方式做到這一點。

我不得不把你的問題分成幾個部分:

  1. 如何在 React 中引用 DOM 節點
  2. 如何創建主題並使其觸發
  3. 如何訂閱 React 中的任何 Observable (useEffect)

獲取對 DOM 節點的引用

如果您要問的只是如何引用 DOM 節點,經驗法則是在 React 中訪問 DOM,您使用useRef 鈎子或類中的 createRef )。

保持您的主題活躍(用於共享事件)

這種方法的好處是您的主題將被創建一次並無限期地保持活動狀態,因此任何東西都可以隨意訂閱和取消訂閱。 我想不出在 React 項目中使用 RxJs 的充分理由,因為 React 有自己的方式來處理事件,所以很難知道這是否能解決你的問題。

function MyRxJsComponent() {

    // establish a stateful subject, so it lives as long as your component does
    const [ clicks$ ] = useState(new Subject());

    // register an event handler on your button click that calls next on your Subject
    return <button onClick={e => clicks$.next(e)}></button>
}

這將創建一個主題,只要您的組件在頁面上處於活動狀態,該主題就會保持活動狀態。 我對如何使用它的最佳猜測是使用 Context 來包含您的主題(將clicks$放在您的上下文中),然后將事件推送到該主題。

請注意我沒有使用 fromEvent 來創建 Observable,因為這個 Observable 將使用您的按鈕創建和銷毀,這使得任何東西都無法在組件之外保持訂閱它。

僅在內部使用 Observable

或者(正如@ArtemDevAkk 所暗示的那樣),您可以只創建您的 Observable 供本地使用並接受將創建和銷毀它的限制(這實際上可能更可取,但同樣,這取決於您實際想要實現的目標)。

function MyRxJsComponent() {

    // get a reference to the button (use <button ref={buttonRef} in your component)
    const buttonRef = useRef(null)
    
    // use useEffect to tell React that something outside of its 
    // control is going to happen (note how the return is _another_ 
    // function that unsubscribes.
    useEffect( () => {

        // create the observable from the buttonRef we created
        const clicks$ = fromEvent(buttonRef.current, 'click')

        clicks$.subscribe( click => {

            // do whatever you need to with the click event
            console.log('button was clicked!', click)
        })
    
        return () => {
            start$.unsubscribe()
        }
    }, [buttonRef]);

    return <button ref={buttonRef}>Click me!</button>;
}

但是你應該嗎?

我認為總的來說,我已經在上面展示了如何使用狀態來讓主題保持活動狀態,只要你需要; 您可以使用 useEffect() 訂閱可觀察對象並在不再需要時取消訂閱。 (我沒有在本地測試過樣本,所以可能需要做一些小調整..)

我提到使用 Context 與其他組件共享您的主題,這是我可以想象 RxJs 在 React 中有用的一種方式。

不過,最終,如果這就是你想做的所有事情,那么在 React 中有更好的方法來處理事件。 一個簡單的<button onClick={() => console.log('clicked')}>可能就是你所需要的。 React 本身就是一個響應式庫,並沒有真正設計為包含 Observable 可以包含的狀態量 - 您的視圖旨在簡化存儲在其他地方的狀態投影。 出於同樣的原因,通常建議您不要嘗試引用特定元素,除非您有特殊原因這樣做。

const buttonRef = useRef(null)
useEffect( () => {
    const start$ = fromEvent(buttonRef.current, 'click').subscribe( click => {
        console.log('click event :', click)
    })

    return () => {
        start$.unsubscribe()
    }
}, [])

將引用添加到按鈕

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM