简体   繁体   English

我如何在 React 中使用 RXJS fromEvent?

[英]How do I use RXJS fromEvent in React?

I'm trying to log the click event on a button in react:我正在尝试在按钮上记录点击事件以做出反应:

const InputBox = () => {
  const clicky = fromEvent(
    document.getElementById('clickMe'),
    'click'
  ).subscribe(clickety => console.log({ clickety }));

  return (
    <button id="clickMe" type="button">
      Click Me
    </button>
  );
};

I get the following error 'Invalid event target'我收到以下错误“无效的事件目标”

在此处输入图像描述

The setup seems to be fine.设置似乎没问题。 If I replace document.getElementById('clickMe') with document then it logs the clicks.如果我用 document 替换document document.getElementById('clickMe')然后它记录点击。 But that logs any click in the document and I just want the clicks on the button in question.但这会记录文档中的任何点击,我只想点击相关按钮。

I tried using a ref instead...我尝试改用 ref ...

const InputBox = () => {
  const buttonEl = React.useRef(null);

  const clicky = fromEvent(buttonEl.current, 'click').subscribe(clickety =>
    console.log({ clickety })
  );

  return (
    <button ref={buttonEl} type="button">
      Click Me
    </button>
  );
};

...but then I get the same 'Invalid event target' error. ...但随后我收到相同的“无效事件目标”错误。

Can someone help me understand why this is an invalid event target and how to fix this so that I can use fromEvent in react.有人可以帮助我理解为什么这是一个无效的事件目标以及如何解决这个问题以便我可以在反应中使用 fromEvent。


Update更新

The problem was that I did not register the observable when mounting the react components.问题是我在安装反应组件时没有注册可观察对象。

If you do this, you must also unmount the component when unmount.如果这样做,则在卸载时还必须卸载该组件。

This works for me now.这现在对我有用。

const InputBox = () => {
  React.useEffect(() => {
    const click$ = fromEvent(
      document.getElementById('clickMe'),
      'click'
    ).subscribe(clickety => console.log({ clickety }));
    return () => click$.unsubscribe();
  }, []);

  return (
    <button id="clickMe" type="button">
      Click Me
    </button>
  );
};

Wrap it in useEffect() that's when the dom is ready将其包裹在useEffect()中,即 dom 准备就绪

const InputBox = () => {
  const buttonEl = React.useRef(null);

  useEffect(() => {
    const clicky = fromEvent(buttonEl.current, 'click').subscribe(clickety =>
      console.log({ clickety })
    );

    return () => clicky.unsubscribe();
  }, []);

  return (
    <button ref={buttonEl} type="button">
      Click Me
    </button>
  );
};

I'm making a couple of assumptions, hoping to present a more generic solution:我做了几个假设,希望提出一个更通用的解决方案:

  • there's nothing special about a MouseEvent . MouseEvent没有什么特别之处。 We're trying to have an Observable of a certain type, owned by a component, and a way to update it.我们试图拥有一个特定类型的Observable ,由一个组件拥有,以及一种更新它的方法。
  • using the Observable is a concern that should be separate from creating it, so it can be passed on to other components, combined with other observables, etc.使用Observable是一个应该与创建它分开的问题,因此它可以传递给其他组件,与其他 observable 组合等。
  • using ref s to attach functionality to buttons is both confusing (since highly non-standard) and not very flexible (what happens if you want to pass that handler somewhere else?)使用ref将功能附加到按钮既令人困惑(因为高度非标准)又不是很灵活(如果您想将该处理程序传递到其他地方会发生什么?)

I'm combining two things in the snippet:我在片段中结合了两件事:

  • a createObservableWithNext function I described in another answer .我在另一个答案中描述的createObservableWithNext function 。 It returns an Observable , and a next function to update it.它返回一个Observable和一个next function 来更新它。
  • useObservable from the wonderful react-use package. useObservable来自精彩的react-use package。 Basically handles subscribing and unsubscribing to observables.基本上处理订阅和取消订阅 observables。
const FancyButton = () => {
  const { observable, next } = React.useRef(
    createObservableWithNext<MouseEvent<HTMLButtonElement>>()
  ).current;

  const latestClick = useObservable(observable);

  React.useEffect(() => {
    if (latestClick) {
      console.log(`clicked at ${latestClick.pageX} ${latestClick.pageY}`);
    }
  }, [latestClick]);

  return (
      <button onClick={next}>
        Next click
      </button>
  )
};

did you try by query selector?您是否尝试过查询选择器? like this像这样

const InputBox = () => {
  const clicky = fromEvent(document.querySelector('button'),'click')
     .subscribe(clickety => console.log({ clickety }));

  return (
    <button type="button">
      Click Me
    </button>
  );
};

that's works for me这对我有用

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在严格模式下将HammerJS中的RxJS fromEvent()与HammerJS一起使用 - How to use RxJS fromEvent() with HammerJS in strict mode Angular - 如何防止来自事件的 RxJs 中的 XSS 攻击? - Angular - how to prevent XSS attacks in RxJs fromEvent? 你将如何在 rxjs 中结合 Scheduler.animationFrame 和 fromEvent(window, &#39;scroll&#39;) 流? - How do would you combine Scheduler.animationFrame and fromEvent(window, 'scroll') streams in rxjs? 如何获取使用.fromEvent创建的Observable的事件名称 - How do I get event name of Observable created with .fromEvent 当我使用 runOutsideAngular fromEvent 时如何处理更改检测? - How to handle change detection when I use runOutsideAngular fromEvent? 如何在 Electron 渲染器进程中使用像 RxJs 这样的模块? - How do I use modules like RxJs in the Electron renderer process? 我如何将`do`用作RxJS lettable运算符? - How would I use `do` as an RxJS lettable operator? RxJS Observable.fromEvent数据 - RxJS Observable.fromEvent data 如何在 object 方法上使用 fromEvent 而不是 bindCallback? - How to use fromEvent instead of bindCallback on an object method? 如何在反应原生 textInput 中使用 rxjs debounceTime - how to use rxjs debounceTime in react native textInput
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM