【实例】React 状态管理库 MobX Redux 入门及对比

在这里插入图片描述

上一篇:【实例】React 组件传值方法: Props、回调函数、Context、路由传参

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 也挺严谨的。
一张很多地方看到的对比图
在这里插入图片描述

  • 36
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值