[英]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 的答案是一種非常好的方法,但我不確定它是否說明了您打算如何使用數據。 我想提出一種替代方法。 誠然,我為此使用了鈎子,但你可以在老學校的課堂上以類似的方式做到這一點。
我不得不把你的問題分成幾個部分:
獲取對 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.