我如何将 rxjs observables 与普通的 React 组件集成?
How do I integrate rxjs observables with a plain React Component?
我是 Rxjs 的新手,正在尝试学习如何在没有任何外部的情况下将它与简单的 React 组件集成 wrapper/library。我在这里工作:
const counter = new Subject()
class App extends Component {
state = {
number: 0
}
componentDidMount() {
counter.subscribe(
val => {
this.setState({ number: this.state.number + val })
}
)
}
increment = () => {
counter.next(+1)
}
decrement = () => {
counter.next(-1)
}
render() {
return (
<div style={styles}>
Current number {this.state.number}
<br /> <br />
<button onClick={this.increment}>Plus</button>
<button onClick={this.decrement}>Minus</button>
</div>
)
}
https://codesandbox.io/s/02j7qm2xw
麻烦的是,这使用了 Subjects,根据 Ben Lesh 等专家的说法,这是一种已知的反模式:
https://medium.com/@benlesh/on-the-subject-of-subjects-in-rxjs-2b08b7198b93
我试过这样做:
var counter = Observable.create(function (observer) {
// Yield a single value and complete
observer.next(0);
// Any cleanup logic might go here
return function () {
console.log('disposed');
}
});
class App extends Component {
state = {
number: 0
}
componentDidMount() {
counter.subscribe(
val => {
this.setState({ number: this.state.number + val })
}
)
}
increment = () => {
counter.next(+1)
}
decrement = () => {
counter.next(-1)
}
// - render
}
但这失败并出现错误:counter.next is not a function
那么我将如何使用 new Observable()
或 Observable.create()
并将其用于 setState
与普通的 React 组件?
因为 .next()
是 Observer
的方法,不是 Observables
。
Subject
之所以有效,是因为Subject
本身既是observer
又是observable
。当您调用 subject.next()
时,您只是在更新 observable
部分,并通知所有 observers
更改。
Observable
和 Observers
有时会让人很困惑。为了简单起见,可以这样想:Observable
是产生数据的人,a.k.a。 数据生产者;而 Observer
是消费数据的人,a.k.a。 数据消费者。打个简单的比方,消费者吃生产出来的东西。同理,Observer(consumer) observes(eats) the observable (produced).
在您的上下文中(或至少 React/Redux 范例),Subject
效果更好。那是因为 Subject
有状态。它跟踪数据生产的价值(Observable
的工作)。每次可观察对象(Subject 中的对象)更改或更新时,任何订阅 Subject
的 observers
都会收到通知。看到这里类似于 redux 的模式了吗?每次您的 redux store 更新时,您的视图都会收到通知(并因此更新)。事实上,如果你非常习惯响应式编程,你完全可以杜绝redux store的使用,完全用Subject
s and/or BehaviourSubject
s来代替。
对于来自 Ben Lesh 的 post,他只是这样说:尽可能使用 Observable
,仅在真正需要时才使用 Subject
。在那个特定的 post 中,他说点击事件可以只是 Observable
;使用 Subject
是不合适的。但是,在您的上下文中,即 react/redux,使用 Subject
很好 - 因为 Subject
用于跟踪商店的状态,而 NOT 点击事件处理器。
TLDR:
- 如果要跟踪变量的状态,请使用
Subject
.next()
是Observer
的方法,不是Observable
。
我是 Rxjs 的新手,正在尝试学习如何在没有任何外部的情况下将它与简单的 React 组件集成 wrapper/library。我在这里工作:
const counter = new Subject()
class App extends Component {
state = {
number: 0
}
componentDidMount() {
counter.subscribe(
val => {
this.setState({ number: this.state.number + val })
}
)
}
increment = () => {
counter.next(+1)
}
decrement = () => {
counter.next(-1)
}
render() {
return (
<div style={styles}>
Current number {this.state.number}
<br /> <br />
<button onClick={this.increment}>Plus</button>
<button onClick={this.decrement}>Minus</button>
</div>
)
}
https://codesandbox.io/s/02j7qm2xw
麻烦的是,这使用了 Subjects,根据 Ben Lesh 等专家的说法,这是一种已知的反模式: https://medium.com/@benlesh/on-the-subject-of-subjects-in-rxjs-2b08b7198b93
我试过这样做:
var counter = Observable.create(function (observer) {
// Yield a single value and complete
observer.next(0);
// Any cleanup logic might go here
return function () {
console.log('disposed');
}
});
class App extends Component {
state = {
number: 0
}
componentDidMount() {
counter.subscribe(
val => {
this.setState({ number: this.state.number + val })
}
)
}
increment = () => {
counter.next(+1)
}
decrement = () => {
counter.next(-1)
}
// - render
}
但这失败并出现错误:counter.next is not a function
那么我将如何使用 new Observable()
或 Observable.create()
并将其用于 setState
与普通的 React 组件?
因为 .next()
是 Observer
的方法,不是 Observables
。
Subject
之所以有效,是因为Subject
本身既是observer
又是observable
。当您调用 subject.next()
时,您只是在更新 observable
部分,并通知所有 observers
更改。
Observable
和 Observers
有时会让人很困惑。为了简单起见,可以这样想:Observable
是产生数据的人,a.k.a。 数据生产者;而 Observer
是消费数据的人,a.k.a。 数据消费者。打个简单的比方,消费者吃生产出来的东西。同理,Observer(consumer) observes(eats) the observable (produced).
在您的上下文中(或至少 React/Redux 范例),Subject
效果更好。那是因为 Subject
有状态。它跟踪数据生产的价值(Observable
的工作)。每次可观察对象(Subject 中的对象)更改或更新时,任何订阅 Subject
的 observers
都会收到通知。看到这里类似于 redux 的模式了吗?每次您的 redux store 更新时,您的视图都会收到通知(并因此更新)。事实上,如果你非常习惯响应式编程,你完全可以杜绝redux store的使用,完全用Subject
s and/or BehaviourSubject
s来代替。
对于来自 Ben Lesh 的 post,他只是这样说:尽可能使用 Observable
,仅在真正需要时才使用 Subject
。在那个特定的 post 中,他说点击事件可以只是 Observable
;使用 Subject
是不合适的。但是,在您的上下文中,即 react/redux,使用 Subject
很好 - 因为 Subject
用于跟踪商店的状态,而 NOT 点击事件处理器。
TLDR:
- 如果要跟踪变量的状态,请使用
Subject
.next()
是Observer
的方法,不是Observable
。