gpt4 book ai didi

javascript - 如何将 React 状态绑定(bind)到 RxJS 可观察流?

转载 作者:搜寻专家 更新时间:2023-11-01 05:29:55 25 4
gpt4 key购买 nike

有人可以帮我如何将 React State 绑定(bind)到 RxJS Observable 吗?我做了某事,例如

componentDidMount() {
let source = Rx.Observable.of(this.state.val)
}

理想的结果是,每当 this.state.val 更新时(通过 this.setState(...))source 得到更新也是,所以我可以将 source 与其他 RxJS 可观察流结合起来。

但是,在这种情况下,source 只会更新一次,即使在 this.state.val 被更新并且组件被重新渲染之后也是如此。

// Ideal result:
this.state.val = 1
source.subscribe(val => console.log(x)) //=> 1
this.state.val = 2
source.subscribe(val => console.log(val)) //=> 2

// Real result:
this.state.val = 1
source.subscribe(val => console.log(x)) //=> 1
this.state.val = 2
source.subscribe(val => console.log(val)) //=> 1 ???WTH

这可能是因为 componentDidMount() 在 React 生命周期中只调用了一次。所以我将 source 移动到 componentDidUpdate() ,每次渲染组件后都会调用它。然而,结果还是一样。

所以问题是如何在 this.state.val 更新时更新 source

更新:这是我用来解决问题的解决方案,使用 Rx.Subject

// Component file
constructor() {
super(props)
this.source = new Rx.Subject()
_onChangeHandler(e) {
this.source.onNext(e.target.value)
}
componentDidMount() {
this.source.subscribe(x => console.log(x)) // x is updated
}
render() {
<input type='text' onChange={this._onChangeHandler} />
}
//

最佳答案

更新

要抽象出下面的一些复杂性,请使用重组的 mapPropsStreamcomponentFromStream .例如

const WithMouseMove = mapPropsStream((props$) => {
const { handler: mouseMove, stream: mouseMove$ } = createEventHandler();

const mousePosition$ = mouseMove$
.startWith({ x: 0, y: 0 })
.throttleTime(200)
.map(e => ({ x: e.clientX, y: e.clientY }));

return props$
.map(props => ({ ...props, mouseMove }))
.combineLatest(mousePosition$, (props, mousePosition) => ({ ...props, ...mousePosition }));
});

const DumbComponent = ({ x, y, mouseMove }) => (
<div
onMouseMove={mouseMove}
>
<span>{x}, {y}</span>
</div>
);

const DumbComponentWithMouseMove = WithMouseMove(DumbComponent);

原帖

对于 OP 更新答案的稍微更新的答案,使用 rxjs5,我想出了以下内容:

class SomeComponent extends React.Component {
constructor(props) {
super(props);

this.mouseMove$ = new Rx.Subject();
this.mouseMove$.next = this.mouseMove$.next.bind(this.mouseMove$);

this.mouseMove$
.throttleTime(1000)
.subscribe(idx => {
console.log('throttled mouse move');
});
}

componentWillUnmount() {
this.mouseMove$.unsubscribe();
}

render() {
return (
<div
onMouseMove={this.mouseMove$.next}
/>
);
}
}

一些值得注意的补充:

  • onNext() 现在是 next()
  • 绑定(bind)可观察的 next 方法允许它直接传递给 mouseMove 处理程序
  • 应该在 componentWillUnmount Hook 中取消订阅流

此外,在组件 constructor Hook 中初始化的主题流可以作为属性传递给 1+ 个子组件,这些组件都可以使用任何可观察的 next/error 推送到流/完整的方法。 Here's a jsbin example我放在一起演示了多个组件之间共享的多个事件流。

想知道是否有人有关于如何更好地封装此逻辑以简化绑定(bind)和取消订阅等内容的想法。

关于javascript - 如何将 React 状态绑定(bind)到 RxJS 可观察流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33726833/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com