RxJS 在现在的前端用比较少,可是 RxJS 作为呼应式和函数式编程的集大成者,好像被前端开发者遗忘,可能是学习难度大,可能是有愈加便利的解决方案

不是由于 Redux 更具有性价比,而是 RxJS 可以翻开更大的 JS 生态空间

下面咱们先回顾一下 Redux 是如何运作开端。

一、Redux 创立一个 Store 做了哪些工作?

为什么能用 RxJS 代替 Redux ?

以上是一个简略的 Redux 的工作流。从 reducer 到视图派发更新的整个流程

Redux 一般在单页面应用中,与React结合,他的根本运用流程。

  • 定义 Reducer 函数
  • 运用 createStore 函数传入 Reducer 创立 store
  • 订阅函数 store
  • 派发类型更新数据。

以下是一个官网的比如:

import { createStore } from 'redux'
function counterReducer(state = { value: 0 }, action) {
  switch (action.type) {
    case 'counter/incremented':
      return { value: state.value + 1 }
    case 'counter/decremented':
      return { value: state.value - 1 }
    default:
      return state
  }
}
let store = createStore(counterReducer)
store.subscribe(() => console.log(store.getState()))
store.dispatch({ type: 'counter/incremented' })
store.dispatch({ type: 'counter/decremented' })

创立一个 Redux 其实也是需求订阅(subscribe)数据。才能运用 dispatch 来派发行为到 reducer 里面。

二、React Redux 与 React 结合

React Redux 是 React 官方与 Redux 结合,便利在 React 组件中运用 Redux。供给了:

  • Provider 组件
  • 钩子函数

2.1)Redux 的难点

为什么能用 RxJS 代替 Redux ?

初学 Redux 难点便是熟练根据自己的业务完成此流程。

2.2)中心化

Redux 是将数据会集到一个 store 库,会集化数据办理,在大型项目中,你可能不想讲数据会集化,Redux 在新的版本 Redux Toolkit 有了分片等功能开端弥补 Redux 的问题。

初学 Redux 其实仍是有一定难度的,需求灵敏运用 reducer 与 dispatch, 还需求 React 进行结合。并且异步副作用在 Redux 中还欠好处理。

2.3)异步使命处理

Redux 一般不能直接处理异步使命,一般合作

  • Redux-thunk

为什么能用 RxJS 代替 Redux ?

  • Redux-saga

为什么能用 RxJS 代替 Redux ?

对异步使命进行处理。根据以上咱们知道了其实 Redux 其实也具有自己优点和缺点。

三、RxJS 为什么可以代替 Redux ?

为什么能用 RxJS 代替 Redux ?

3.1)React 作为视图层

类似于 React 和 Vue 等框架,虽然组件具有自己的状况办理,可是在杂乱数据联系时力不从心。于是演化出了 Redux 等数据层办理库。可是 RxJS 自身根据事情流,具有强壮的处理数据流才能。与视图层调集便具有了强壮的数据处理才能。

3.2)Redux 作为数据层

经过以上的简介,可以了解 Redux 其实便是一个 store 作为数据层而存在。它一般具有有以下一些操作:

  • 存储数据
  • 取出数据
  • 改动数据
  • 异步处理

3.3) RxJS 作为数据层可以这样做

RxJS 是一个函数式和呼应式的 JavaScript, 自带呼应式数据才能。

一般的可调查目标,只产生一个可调查目标数据。也没有缓存数据的才能。明显欠好,可是 RxJS 完成了 Subject 系列,其中 BehaviorSubject 可以自带初始值,并且也有缓存才能,可以完成跨组件的订阅数据。

BehaviorSubject 是完成 Store 中状况办理的最佳挑选。

四、一个简略的 RxJS 完成 Store

4.1)思考

咱们要完成一个 Store,咱们根据 class 和 React 的 hooks 进行规划。在 Store 需求考虑跨过组件和和跨过页面的状况办理规划。

  • BehaviorSubject 行为主题具有函数数据和初始化才能,是作为状况办理的最佳挑选

4.2)完成一个简略的 Store

import { BehaviorSubject, type SubjectLike } from "rxjs";
export class Store {
  state$;
  constructor() {
    this.state$ = new BehaviorSubject({counter: 10 });
  }
  updateState(data: IState) {
    this.state$.next({ ...data });
  }
  getState(): SubjectLike<any> {
    return this.state$;
  }
  unsubscribe() {
    this.state$.unsubscribe()
  }
}
export const store = new Store()

这个 Store 也非常简略,在结构函数中创立行为主题,然后再 getState 中获取状况主题,已经在 updateState 中运用 next 办法更新主题,最后在 unsubscribe 中取消订阅。

这里咱们实例化一个大局 store, 然后输出,便利在大局运用。

4.3)根据 Store 封装 hooks 便利在 React 组件中运用

import { store } from './store'
export function useStore() {
  const [data, setData] = useState<IState>({ counter: 0 })
  useEffect(() => {
    store.getState().subscribe((v: any) => {
      setData(!v ? { counter: 0 } : v);
    });
    return () => {
      store.unsubscribe()
    }
  }, [])
  const updateData = (data: IState) => {
    store.updateState({...data})
  }
  return [data, updateData]
}

注意: store 是规划考虑在大局运用的,意味着这里的 useStore 是具有跨过页面和组件才能的。其中重要的办法 updateData 是经过在修改 Store 内部的数据进行大局的状况办理。

4.4)用法

export function Sub() {
  const [data, updateData] = useStore()
  return <div>
    counter {data.counter}
    <button onClick={() => updateData({
      counter: data.counter + 1
    })}>+</button>
  </div>
}

一个简略的 Sub 组件中,直接调用 useStore 可以便利进行同步状况办理和内容更新。下面增加一个办法,用于处理异步使命。

4.5)增加异步办法

在 store 类中增加一个异步办法:

class Store {
/* 其他办法*/
// 增加异步办理
  asyncOperation(): Observable<any> {
    return of(/* Your async operation result */).pipe(
      switchMap((result) => {
        // 处理异步操作的结果,并更新状况
        this.updateState({ counter: result });
        return of(result);
      }),
      catchError((error) => {
        // 处理过错
        console.error('Error in async operation:', error);
        return of(null);
      })
    );
  } 
}

asyncOperation 是一个 store 异步办法,运用 of 操作符,经过管道 switchMap 处理异步使命,并返回新的可调查目标,然后运用 catchError 处理过错。

4.6) RxJS 作为状况办理的优点

  • 可以凭借强壮的 RxJS 异步数据处理才能
  • 合作 React hooks 可以磨平 RxJS 代码层面对React代码的侵略
  • 了解 RxJS 的小伙伴,可以拥抱愈加广泛的 JS 生态
  • 合适大型项目

4.7) 缺点

  • 对新手并不友好
  • RxJS 学习曲线比较高
  • 不合适小型项目

五、小结

本文主要重视 RxJS 作为状况办理的才能,经过完成一个简略的 Store 合作 BehaviorSubject 与 React hooks 进行合作完成一个简略的大局状况办理方案。一起也给出了异步数据的处理方案。本文需求对 RxJS 和 React 以及 React 状况管都比较了解,凭借 RxJS 强壮的异步数据流处理才能与 React hooks 结合,可以很好的磨平 RxJS 客观目标对React 组件代码的侵略,在代码层面也坚持了简练。最后也希望本文可以帮助到大家。