title: RxJS and React multiple clicked elements to form single data array
body: <p>So I just started trying to learn rxjs and decided that I would implement it on a UI that I'm currently working on with React (I have time to do so, so I went for it). However, I'm still having a hard time wrapping my head around how it actually works... Not only "basic" stuff like when to actually use a Subject and when to use an Observable, or when to just use React's local state instead, but also how to chain methods and so on. That's all too broad though, so here's the specific problem I have.</p>
  
  <p>Say I have a UI where there's a list of filters (buttons) that are all clickeable. Any time I click on one of them I want to, first of all, make sure that the actions that follow will debounce (as to avoid making network requests too soon and too often), then I want to make sure that if it's clicked (active), it will get pushed into an array and if it gets clicked again, it will leave the array. Now, this array should ultimately include all of the buttons (filters) that are currently clicked or selected.</p>
  
  <p>Then, when the debounce time is done, I want to be able to use that array and send it via Ajax to my server and do some stuff with it.</p>
  
  <pre><code>import React, { Component } from 'react';
  import * as Rx from 'rx';
  
  export default class CategoryFilter extends Component {
   constructor(props) {
      super(props);
  
      this.state = {
          arr: []
      }
  
      this.click = new Rx.Subject();
      this.click
      .debounce(1000)
      // .do(x =&gt; this.setState({
      //  arr: this.state.arr.push(x)
      // }))
      .subscribe(
         click =&gt; this.search(click),
         e =&gt; console.log(`error ---&gt; ${e}`),
         () =&gt; console.log('completed')
      );
   }
  
  search(id) {
      console.log('search --&gt; ', id);
      // this.props.onSearch({ search });
  }
  
  clickHandler(e) {
      this.click.onNext(e.target.dataset.id);
  }
  
  render() {
      return (
          &lt;section&gt;
              &lt;ul&gt;
                  {this.props.categoriesChildren.map(category =&gt; {
                      return (
                          &lt;li
                              key={category._id}
                              data-id={category._id}
                              onClick={this.clickHandler.bind(this)}
                          &gt;
                              {category.nombre}
                          &lt;/li&gt;
                      );
                  })}
              &lt;/ul&gt;
          &lt;/section&gt;
      );
   }
  }
  </code></pre>
  
  <p>I could easily go about this without RxJS and just check the array myself and use a small debounce and what not, but I chose to go this way because I actually want to try to understand it and then be able to use it on bigger scenarios. However, I must admit I'm way lost about the best approach. There are so many methods and different things involved with this (both the pattern and the library) and I'm just kind of stuck here.</p>
  
  <p>Anyways, any and all help (as well as general comments about how to improve this code) are welcome. Thanks in advance!</p>
  
  <p>---------------------------------<strong>UPDATE</strong>---------------------------------</p>
  
  <p>I have implemented a part of Mark's suggestion into my code, but this still presents two problems:</p>
  
  <p>1- I'm still not sure as to how to filter the results so that the array will only hold IDs for the buttons that are clicked (and active). So, in other words, these would be the actions:</p>
  
  <ul>
  <li>Click a button once -> have its ID go into array</li>
  <li>Click same button again (it could be immediately after the first
  click or at any other time) -> remove its ID from array.</li>
  </ul>
  
  <p>This has to work in order to actually send the array with the correct filters via ajax. Now, I'm not even sure that this is a possible operation with RxJS, but one can dream... (Also, I'm willing to bet that it is).</p>
  
  <p>2- Perhaps this is an even bigger issue: how can I actually maintain this array while I'm on this view. I'm guessing I could use React's local state for this, just don't know how to do it with RxJS. Because as it currently is, the buffer returns only the button/s that has/have been clicked before the debounce time is over, which means that it "creates" a new array each time. This is clearly not the right behavior. It should always point to an existing array and filter and work with it.</p>
  
  <p>Here's the current code:</p>
  
  <pre><code>import React, { Component } from 'react';
  import * as Rx from 'rx';
  
  export default class CategoryFilter extends Component {
   constructor(props) {
      super(props);
  
      this.state = {
          arr: []
      }
  
      this.click = new Rx.Subject();
      this.click
      .buffer(this.click.debounce(2000))
      .subscribe(
          click =&gt; console.log('click', click),
          e =&gt; console.log(`error ---&gt; ${e}`),
          () =&gt; console.log('completed')
      );
   }
  
  search(id) {
      console.log('search --&gt; ', id);
      // this.props.onSearch({ search });
  }
  
  clickHandler(e) {
      this.click.onNext(e.target.dataset.id);
  }
  
  render() {
      return (
          &lt;section&gt;
              &lt;ul&gt;
                  {this.props.categoriesChildren.map(category =&gt; {
                      return (
                          &lt;li
                              key={category._id}
                              data-id={category._id}
                              onClick={this.clickHandler.bind(this)}
                          &gt;
                              {category.nombre}
                          &lt;/li&gt;
                      );
                  })}
              &lt;/ul&gt;
          &lt;/section&gt;
      );
   }
  }
  </code></pre>
  
  <p>Thanks, all, again!</p>