如何将rxjs observable与一个简单的React组件集成?

时间:2017-10-11 04:12:02

标签: reactjs rxjs observable rxjs5

我是Rxjs的新手,我正在尝试学习如何将它与一个简单的React组件集成,而不需要任何外部包装器/库。我在这里工作了这个:

library(caret)
library(mlbench) # for the Sonar dataset
data(Sonar) #response is "Class"

# Split data into test and train
train_inds = createDataPartition(y = Sonar$Class, p = .75, list = FALSE)
X_train = Sonar[train_inds, ]
X_test = Sonar[-train_inds, ]

# Fit model using 5-fold cross validation to get optimal alpha and lambda
ctrl = trainControl(method = "cv", number = 5)
fit  =  train(Class ~ ., data = X_train, method = "glmnet",
              preProc = c("center", "scale"),
              trControl = ctrl)
fit # print optimal values of alpha and lambda

# Get confusion matrix for test data (as well as specificity, accuracy etc)
yhats <- predict(fit, newdata = X_test, type = "raw")
confusionMatrix(yhats, X_test$Class)

https://codesandbox.io/s/02j7qm2xw

我遇到麻烦的是,根据像Ben Lesh这样的专家,这使用了一个已知反模式的主题: https://medium.com/@benlesh/on-the-subject-of-subjects-in-rxjs-2b08b7198b93

我试过这样做:

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

但是这失败了错误: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 functionnew Observable()并使用普通的React组件将其用于Observable.create()

1 个答案:

答案 0 :(得分:5)

由于.next()Observer方法, Observables

Subject之所以有效,只是因为Subject本身既是observer又是observable。当您致电subject.next()时,您只需更新observable部分,并通知所有observers有关此更改的信息。

ObservableObservers有时可能会让人感到困惑。为简单起见,请考虑这种方式:Observable是生成数据的人,a.k.a。数据生成者;而Observer是使用数据的人,a.k.a。数据使用者。简单来说,消费者会吃掉所生产的东西。出于同样的原因,观察者(消费者)观察(吃掉)可观察的(产生的)。

在您的上下文中(或至少是React / Redux范例),Subject效果更好。那是因为Subject有州。它记录了数据生成的价值(Observable的工作)。每当observable(Subject中的一个)发生更改或更新时,任何订阅observers的{​​{1}}都会收到通知。在这里看到类似于redux的模式?每次更新redux商店时,您的视图都会得到通知(并因此更新)。实际上,如果您非常习惯于反应式编程,则可以完全取消使用redux存储,并完全用Subject和/或Subject替换它们。

对于Ben Lesh的帖子,他只是说明了这一点:如果可能,请始终使用BehaviourSubject,只在真正需要时使用Observable。在那篇特定的帖子中,他说明点击事件只能是Subject;使用Observable将是完全错误的。但是,在您的上下文中,即react / redux,使用Subject很好 - 因为Subject用于跟踪商店的状态,而不是点击事件处理程序。

<强> TLDR:

  1. 如果要跟踪变量的状态,请使用Subject
  2. Subject.next()的方法,而不是Observer