我刚开始尝试学习rxjs,并决定在我目前正在使用React的UI上实现它(我有时间这样做,所以我就去做了)。然而,我仍然很难理解它的工作原理...不仅是“基础”知识,例如何时实际使用Subject和何时使用Observable,或者何时只需使用React的本地状态,还包括如何链接方法等。虽然这些都太广泛了,但这里是我遇到的具体问题。
假设我有一个UI,其中有一系列可单击的筛选器(按钮)。每次单击其中一个时,首先要确保后续操作会进行防抖处理(以避免过早过频地发出网络请求),然后要确保如果被单击(处于活动状态),则将其推入数组中,如果再次单击,则将其从数组中删除。现在,该数组应包括当前已单击或选择的所有按钮(筛选器)。
然后,在防抖时间结束时,我希望能够使用该数组并通过Ajax将其发送到我的服务器并执行一些操作。
我本可以不使用RxJS来检测数组并使用小的防抖等方法,但我选择了这种方式,因为我想试图理解它,并能够在更大的场景中使用它。然而,我必须承认,我对最佳方法已经迷失了方向。涉及到很多方法和不同的事情(模式和库),我被困在这里。
无论如何,欢迎任何和所有的帮助(以及关于如何改进此代码的一般评论)。提前致谢!
---------------------------------更新内容---------------------------------
我已经在我的代码中实现了Mark建议的部分,但仍存在两个问题:
1. 我仍然不确定如何过滤结果,使得数组只保持所点击按钮的ID(活动)。因此,换句话说,这将是以下操作:
单击按钮一次 -> 将其ID放入数组中
再次单击同一按钮(可能是在第一个点击后立即进行,也可能是在任何其他时间) -> 从数组中删除其ID。
这必须有效,以便通过ajax实际发送带有正确过滤器的数组。现在,我甚至不确定这是否是RxJS可以实现的操作,但人们可以梦想... (而且,我愿意打赌这是可以的)。
2. 也许这是一个更大的问题:我如何在这个视图上实际维护这个数组。我猜我可以在这个任务中使用React的本地状态,只是不知道如何用RxJS实现它。因为目前情况下,缓冲区仅在防抖时间结束之前单击的按钮返回,这意味着它每次都会“创建”一个新数组。这显然不是正确的行为。它应该总是指向现有的数组并对其进行过滤和处理。
以下是当前的代码:
感谢大家再次的支持!
假设我有一个UI,其中有一系列可单击的筛选器(按钮)。每次单击其中一个时,首先要确保后续操作会进行防抖处理(以避免过早过频地发出网络请求),然后要确保如果被单击(处于活动状态),则将其推入数组中,如果再次单击,则将其从数组中删除。现在,该数组应包括当前已单击或选择的所有按钮(筛选器)。
然后,在防抖时间结束时,我希望能够使用该数组并通过Ajax将其发送到我的服务器并执行一些操作。
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 => this.setState({
// arr: this.state.arr.push(x)
// }))
.subscribe(
click => this.search(click),
e => console.log(`error ---> ${e}`),
() => console.log('completed')
);
}
search(id) {
console.log('search --> ', id);
// this.props.onSearch({ search });
}
clickHandler(e) {
this.click.onNext(e.target.dataset.id);
}
render() {
return (
<section>
<ul>
{this.props.categoriesChildren.map(category => {
return (
<li
key={category._id}
data-id={category._id}
onClick={this.clickHandler.bind(this)}
>
{category.nombre}
</li>
);
})}
</ul>
</section>
);
}
}
我本可以不使用RxJS来检测数组并使用小的防抖等方法,但我选择了这种方式,因为我想试图理解它,并能够在更大的场景中使用它。然而,我必须承认,我对最佳方法已经迷失了方向。涉及到很多方法和不同的事情(模式和库),我被困在这里。
无论如何,欢迎任何和所有的帮助(以及关于如何改进此代码的一般评论)。提前致谢!
---------------------------------更新内容---------------------------------
我已经在我的代码中实现了Mark建议的部分,但仍存在两个问题:
1. 我仍然不确定如何过滤结果,使得数组只保持所点击按钮的ID(活动)。因此,换句话说,这将是以下操作:
单击按钮一次 -> 将其ID放入数组中
再次单击同一按钮(可能是在第一个点击后立即进行,也可能是在任何其他时间) -> 从数组中删除其ID。
这必须有效,以便通过ajax实际发送带有正确过滤器的数组。现在,我甚至不确定这是否是RxJS可以实现的操作,但人们可以梦想... (而且,我愿意打赌这是可以的)。
2. 也许这是一个更大的问题:我如何在这个视图上实际维护这个数组。我猜我可以在这个任务中使用React的本地状态,只是不知道如何用RxJS实现它。因为目前情况下,缓冲区仅在防抖时间结束之前单击的按钮返回,这意味着它每次都会“创建”一个新数组。这显然不是正确的行为。它应该总是指向现有的数组并对其进行过滤和处理。
以下是当前的代码:
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 => console.log('click', click),
e => console.log(`error ---> ${e}`),
() => console.log('completed')
);
}
search(id) {
console.log('search --> ', id);
// this.props.onSearch({ search });
}
clickHandler(e) {
this.click.onNext(e.target.dataset.id);
}
render() {
return (
<section>
<ul>
{this.props.categoriesChildren.map(category => {
return (
<li
key={category._id}
data-id={category._id}
onClick={this.clickHandler.bind(this)}
>
{category.nombre}
</li>
);
})}
</ul>
</section>
);
}
}
感谢大家再次的支持!