【问题标题】:How do I use RXJS fromEvent in React?如何在 React 中使用 RXJS fromEvent?
【发布时间】:2019-10-14 03:26:12
【问题描述】:

我正在尝试在 react 中记录按钮的点击事件:

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

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

我收到以下错误“事件目标无效”

设置似乎很好。如果我将document.getElementById('clickMe') 替换为document,那么它会记录点击次数。但这会记录文档中的任何点击,我只想点击相关按钮。

我尝试使用 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>
  );
};

...但是我得到相同的“无效事件目标”错误。

谁能帮我理解为什么这是一个无效的事件目标以及如何解决这个问题,以便我可以在反应中使用 fromEvent。


更新

问题是我在安装 react 组件时没有注册 observable。

如果这样做,您还必须在卸载时卸载组件。

这对我有用。

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>
  );
};

【问题讨论】:

  • 注册时DOM上的按钮还在吗?
  • componentDidMount注册监听器

标签: javascript reactjs rxjs


【解决方案1】:

将其包裹在 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>
  );
};

【讨论】:

  • 这很有效,谢谢。不需要使用 refs,与 Id 选择器一起使用。对于遵循此操作的其他人,您只需要注册 onMount,因此请将您的依赖项数组保持为空,而不是在每个渲染上挂载。 const InputBox = () =&gt; { React.useEffect( () =&gt; fromEvent(document.getElementById('clickMe'), 'click').subscribe( clickety =&gt; console.log({ clickety }) ), [] ); return ( &lt;button id="clickMe" type="button"&gt; Click Me &lt;/button&gt; ); };
  • ...并且不要忘记取消订阅``` const InputBox = () => { React.useEffect(() => { const click$ = fromEvent( document.getElementById('clickMe' ), 'click' ).subscribe(clickety => console.log({ clickety })); return () => click$.unsubscribe(); }, []);返回(); }; ```
  • 你也可以使用主题
  • 我不想使用主题,因为这会迫使您弄乱可观察对象的内部并处理自己的错误,我更喜欢开箱即用的解决方案。
【解决方案2】:

您是否尝试过查询选择器? 像这样

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

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

这对我有用

【讨论】:

  • 查询选择器破坏了这一点,即注册任何按钮。我想要那个特定的按钮。这只是一个使用 useEffect 安装的情况,使用 getElementById 工作正常。
  • 除了将监听器附加到某个按钮(可能不是这个按钮)之外,这也是有问题的,因为它不考虑 React 的渲染生命周期:这不会在第一个期间/之后附加监听器渲染(尽管它应该在第二次渲染期间)并且它将导致第二次之后的每个渲染重复订阅。
猜你喜欢
  • 2019-02-10
  • 1970-01-01
  • 2021-09-19
  • 2018-07-03
  • 1970-01-01
  • 1970-01-01
  • 2018-01-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多