问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

React状态管理库MobX和Redux入门及对比

创作时间:
作者:
@小白创作中心

React状态管理库MobX和Redux入门及对比

引用
CSDN
1.
https://blog.csdn.net/cherry__yu/article/details/136853254

在React应用开发中,状态管理是一个核心问题。本文将介绍两种主流的状态管理库:MobX和Redux,并通过实例演示它们的基本用法和区别。

MobX

MobX 是一个状态管理库,它提供了一种响应式的数据流方案,使得状态的变化能够自动地反映到相关的组件中。

MobX 的核心理念是可观察的状态(Observable State)和响应式行为(Reactive Behavior)。将状态标记为可观察的后,MobX 可以自动跟踪状态的变化,并且在状态发生变化时自动通知相关的组件进行更新。

概念

  1. State(状态)
    状态 是驱动应用的数据。通常有像待办事项列表这样的业务数据状态,还有像当前已选元素的视图状态。

  2. action(动作)
    动作 是改变状态的代码。用户事件、后端数据推送、预定事件、等等。
    在 MobX 中可以显式地定义动作,它可以帮你把代码组织的更清晰。如果是在严格模式下使用 MobX 的话,MobX 会强制只有在动作之中才可以修改状态。

  3. Derivations(衍生)
    任何源自状态并且不会再有任何进一步的相互作用的东西就是衍生。MobX 区分了两种类型的衍生:

  • Computed values(计算值): 它们是永远可以使用纯函数从当前可观察状态中衍生出的值。黄金法则: 如果你想创建一个基于当前状态的值时,请使用 computed。(所有的计算值都应该是纯净的。它们不应该用来改变状态)
  • Reactions(反应): Reactions 是当状态改变时需要自动发生的副作用。

原则

MobX 支持单向数据流,也就是动作改变状态,而状态的改变会更新所有受影响的视图。

例子

MobX 将一个应用变成响应式的可归纳为以下三个步骤:

  1. 定义状态并使其可观察
    可以用任何你喜欢的数据结构来存储状态,如对象、数组、类。循环数据结构、引用都可以。只要确保所有会随时间流逝而改变的属性打上 mobx 的标记使它们变得可观察即可。
import {observable} from 'mobx';
var appState = observable({
    timer: 0
});
  1. 创建视图以响应状态的变化
    用 observer 来定义观察者组件。
import {observer} from 'mobx-react';
@observer
class TimerView extends React.Component {
    render() {
        return (
            <button onClick={this.onReset.bind(this)}>
                Seconds passed: {this.props.appState.timer}
            </button>
        );
    }
    onReset() {
        this.props.appState.resetTimer();
    }
};
ReactDOM.render(<TimerView appState={appState} />, document.body);
  1. 更改状态
    只有在严格模式(默认是不启用)下更新被观察的状态才需要 action 包装。 建议使用 action,因为它将帮助你更好地组织应用,并表达出一个函数修改状态的意图。 同时,它还自动应用事务以获得最佳性能。
appState.resetTimer = action(function reset() {
    appState.timer = 0;
});
setInterval(action(function tick() {
    appState.timer += 1;
}), 1000);

Redux

在 Redux 中,所有的状态被保存在 store 状态树中(一个应用程序中只能有一个)。任何组件都可以直接从 store 中访问特定对象的状态。如果要更改状态,需要分发一个 action,分发在这里意味着将可执行信息发送到 store,然后 store 将 action 代理给相关的 reducer。reducer是一个纯函数,它可以查看之前的状态,执行一个 action 并且返回一个新的状态。

例子

App.js 是应用程序的入口文件。使用 Provider 组件包裹整个应用程序,并传递 Redux store 作为属性。这样,应用程序中的所有组件都能够访问 Redux store 中的状态和动作。

// src/App.js
import React from 'react';
import Counter from './components/Counter';
import { Provider } from 'react-redux';
import store from './store';
function App() {
  return (
    <Provider store={store}>
      <div>
        <h1>React Redux Counter App</h1>
        <Counter />
      </div>
    </Provider>
  );
}
export default App;

在组件里使用 useSelector 钩子从 Redux store 中获取状态,并使用 useDispatch 钩子获取 dispatch 函数用于分发动作。

// src/components/Counter.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from '../actions';
function Counter() {
  const counter = useSelector(state => state);
  const dispatch = useDispatch();
  return (
    <div>
      <h1>Counter: {counter}</h1>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
    </div>
  );
}
export default Counter;

action 文件定义了两个动作创建函数 increment 和 decrement。这些动作创建函数用于创建描述动作的对象,并且这些对象包含一个 type 属性,指示要执行的动作类型。然后定义 reducer,Reducer 函数接收两个参数:当前状态(state)和要执行的动作(action)。根据不同的动作类型,它会返回一个新的状态。创建 redux store,将 reducer 作为参数传进去。

// src/actions/index.js
export const increment = () => {
  return {
    type: 'INCREMENT'
  };
};
export const decrement = () => {
  return {
    type: 'DECREMENT'
  };
};
// src/reducers/index.js
const counterReducer = (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1;
    case 'DECREMENT':
      return state - 1;
    default:
      return state;
  }
};
export default counterReducer;
// src/store/index.js
import { createStore } from 'redux';
import counterReducer from '../reducers';
const store = createStore(counterReducer);
export default store;

对比

Redux 强调不可变性和可预测性,而 MobX 更灵活,也少很多模版代码,状态的自动追踪和更新也使开发更方便。但是优点也同时可能是缺点,太灵活对于讲究严格的大型应用可能会有问题。但是私以为只要组织的好,规范代码结构,用 MobX 也挺严谨的。

一张很多地方看到的对比图

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号