重学 Rxjs —— 在 react 中使用

1,007 阅读2分钟

「这是我参与2022首次更文挑战的第36天,活动详情查看:2022首次更文挑战

经过前面的一系列学习,Rxjs 的理论知识现在已经基本具备了,接下来就是在应用中尝试使用,在实际开发中我们往往会选择 UI 库或框架来构建应用,这里主要还是以 vue、react、angular 为主,其中 angular 是一个庞大的框架,官方提供了结合 Rxjs 使用的一套最佳实践方案,因此很多 Rxjs 用户也是 angular 用户。但是实际上 Rxjs 和 vue 或 react 这些库也是可以很好的共同运行,vue 和 react 的定位是 UI 层开发库,它控制的只有用户交互层内容,对数据层如何管理没有过多要求,因此我们可以自己选用数据管理方案,而 Rxjs 最擅长的就是数据流处理因此这里可以很好的一起运行,本文就以 react 为例看一下如何在 react 应用中发挥 Rxjs 的作用。

我们先来写一个简单的 React 组件:

function Counter() {
	const [num, setNum] = useState(0);
	const inc = () => setNum(p => p + 1);
	const dec = () => setNum(p => p - 1);
	return (
		<div>
			<div>Count: {num}</div>
			<div onClick={inc}>+</div>
			<div onClick={dec}>-</div>
		</div>
	);
}

这里有一个数字和两个按钮点击 + 数字加一,点击 - 数字减一,这就是一个非常简单的计数器应用,接下来我们看如何使用 Rxjs 来管理数据。

const count = new Subject();
function Counter() {
	const [num, setNum] = useState(0);
	useEffect(() => {
		count.scan((res, inc) => res + inc, 0).subscribe(n => setNum(n));
	}, []);
	const inc = () => count.next(1);
	const dec = () => count.next(1);
	return (
		<div>
			<div>Count: {num}</div>
			<div onClick={inc}>+</div>
			<div onClick={dec}>-</div>
		</div>
	);
}

这里使用一个 Subject 接收消息,把原本操作 state 的行为转换为向 Subject 发送数据,利用 scan 把每次收到的数据收集起来进行一个计算,把最终的结果发送到 UI 上。在本例中显然没有必要,这样做除了增加代码复杂度没有任何好处,但是在某些复杂的场景下这是一种思路。

这里把原来操作 state 的行为变为 next 发送数据的行为是不是感觉在哪里见过?我们常用的 redux 好像也是这样的,原本操作的是 state,使用 redux 变为触发 action,最终从 store 中获取数据。实际上使用 Rxjs 可以很容实现 redux 的相关功能,下一届我们就看下这部分内容。