zoukankan      html  css  js  c++  java
  • redux和mobx比较(二)

    Redux

    Redux 是 JavaScript 状态容器,提供可预测化的状态管理。

    redux

    三大核心

    在 Redux 中,最为核心的概念就是 action 、reducer、store 以及 state,那么具体是什么呢?

    • Action:是把数据从应用传到 store 的有效载荷。它是 store 数据的唯一来源
    • Reducer:指明如何更新 state
    • Store:把 action、Reducer 联系到一起的对象,负责维持、获取和更新state

    数据流

    严格的单向数据流是 Redux 架构的设计核心。

    Redux 应用中数据的生命周期遵循下面 4 个步骤:

    • 调用 store.dispatch(action) 触发 action
    • Redux store 调用传入的 reducer 函数
    • 根 reducer 应该把多个子 reducer 输出合并成一个单一的 state 树
    • Redux store 保存了根 reducer 返回的完整 state 树

    搭配 React

    react-redux

    核心库:

    1
    2
    3
    4
    5
    6
    7
    react
    react-dom
    react-router
    react-router-redux //利用react-router-redux提供的syncHistoryWithStore我们可以结合store同步导航事件
    redux
    react-redux
    react-thunk/react-saga/redux-logger //middleware

    目录结构:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ├─app
    │ ├─actions //redux动作生成器
    │ ├─assets //静态资源
    │ ├─compontens //UI组建
    │ ├─containers //容器组件
    │ ├─reducers
    │ ├─routes
    │ ├─store
    │ └─utils //工具函数
    └─dist //发布目录

    不过使用过 Redux 的人会有这些痛点:难懂的 API、复杂的逻辑、过多的代码侵入。Redux 采用单一根节点、函数式编程、动作分离管理(似乎让项目很容易管理),这些都是 Redux 过于复杂的原因。然这里并不是说 Redux 不好。基于项目本身,寻找一个最适合的框架才是优的解决方案。

    Mobx

    MobX 是一个经过战火洗礼的库,它通过透明的函数响应式编程(transparently applying functional reactive programming - TFRP)使得状态管理变得简单和可扩展。

    比起Redux,Mobx基于观察者模式,采用多节点管理数据,是一个很轻量、入手简单、代码耦合小的数据框架。

    核心概念

    数据流

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

    mobx-fow

    它由几个部分组成:Actions、State、Computed Values、Reactions。使用 MobX 将一个应用变成响应式的可归纳为以下步骤:

    • 通过事件驱动(UI 事件、网络请求…)触发 Actions
    • 在 Actions 中修改了 State 中的值,这里的 State 既应用中的 store 树(存储数据)
    • 然后根据新的 State 中的数据计算出所需要的计算属性(computed values)值
    • 响应(react)到 UI 视图层

    Observable state(可被观察的状态)

    MobX 为现有的数据结构(如对象,数组和类实例)添加了可观察的功能。 通过使用 @observable 装饰器来给你的类属性添加注解就可以简单地完成这一切。这样改属性就变成了“被观察者”。

    1
    2
    3
    class Store {
    @observable a = 'Hello Word!';
    }

    Observer(观察者)

    observer 函数装饰器可以用来将 React 组件转变成响应式组件。 它用 mobx.autorun 包装了组件的 render函数以确保任何组件渲染中使用的数据变化时都可以强制刷新组件。 observer 是由单独的 mobx-react 包提供的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @observer
    class Index extends Component {
    render() {
    return (
    <p>
    {this.props.Store.a}
    </p>
    )
    }
    }

    这样 Index 组件就变成了一个响应式的组件(智能组件),当“被观察者”改变时,该组件就会自动更新。

    componentWillReact (生命周期钩子)

    React 组件通常在新的堆栈上渲染,这使得通常很难弄清楚是什么导致组件的重新渲染。 当使用 mobx-react 时可以定义一个新的生命周期钩子函数 componentWillReact。当组件因为它观察的数据发生了改变,它会安排重新渲染,这个时候 componentWillReact 会被触发。这使得它很容易追溯渲染并找到导致渲染的操作(action)。

    inject(注入)

    inject 函数装饰器可以将 Store 数据注入到组件当中。inject 是由单独的 mobx-react 包提供的。

    1
    @inject("store")

    Computed values(计算值)

    使用 MobX,可以定义在相关数据发生变化时自动更新的值。 通过 @computed 装饰器调用 的getter / setter 函数来进行使用。

    1
    2
    3
    4
    5
    6
    7
    class ItemsStore {
    @observable items = [];

    @computed get total() {
    return this.items.length;
    }
    }

    当添加了一个新的 items 时,MobX 会确保 total 自动更新。

    Action(动作)

    action 是任一一段可以改变状态的代码。具体实现代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class HomeStore {
    @observable num = 0;

    @action plus = () => {
    this.num = ++this.num
    }
    @action minus = () => {
    this.num = --this.num
    }
    }

    如果是在严格模式:

    1
    2
    import { useStrict } from 'mobx';
    useStrict(true);

    那么 MobX 会强制只有在动作之中才可以修改状态。对于任何不使用动作的状态修改,MobX 都会抛出异常。

    异步 Action

    action 包装/装饰器只会影响当前运行的函数,而不会影响当前函数调度(但不是调用)的函数! 这意味着如果你有一个 setTimeout、promise 的 then 或 async 语句,并且在回调函数中某些状态改变了,这些回调函数也应该包装在 action 中。可以使用 action 关键字来包装 promises 回调函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @action
    fetchData = (url) => {
    fetch(url).then(
    action('fetchRes', res => {
    return res.json()
    })).then(
    action('fetchSuccess', data => {
    // TODO

    })).catch(
    action('fetchError', e => {
    // err
    }))
    }

    异步 action 实现的方式还有多种,这里只列举了 action 关键子的模式

    在 React 中使用 Mobx

    在 React 中使用 MobX 需要用到 mobx-react。
    其提供了 Provider 组件用来包裹最外层组件节点,并且传入 store 传递给后代组件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    import React from 'react';
    import ReactDOM from 'react-dom';
    import {useStrict} from 'mobx';
    import {HashRouter as Router} from 'react-router-dom'
    import {Provider} from 'mobx-react';
    import * as stores from './store';

    import App from './compontens/App'

    useStrict(true) // 不允许在动作之外进行状态修改

    ReactDOM.render(
    <Provider store={stores}>
    <Router>
    <App/>
    </Router>
    </Provider>, document.getElementById('root')
    );

    使用 @inject 给组件注入其需要的 store(利用 React context 机制);
    通过 @observer 将 React 组件转化成响应式组件,它用 mobx.autorun 包装了组件的 render 函数以确保任何组件渲染中使用的数据变化时都可以强制刷新组件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import React, {Component} from 'react'
    import {observer, inject} from 'mobx-react'
    import {withRouter} from 'react-router-dom'

    @withRouter @inject('store') @observer
    class App extends Component {

    render() {
    return (
    <div className="main">
    //……
    </div>
    )
    }
    }

    export default App

    其中 @withRouter 是 router 的 参数传入到组件中。

  • 相关阅读:
    .net下的span和memory
    linux下mysql自动备份脚本
    mysqldump参数详细说明(转)
    Apache参数的优化(转)
    shell中set的用法(转)
    [转贴] start-stop-daemon命令
    Linux命令service
    分享三个好用的装饰器(转)
    python语法32[装饰器decorator](转)
    mongodb exception in initAndListen: 12596 old lock file, terminating解决方法
  • 原文地址:https://www.cnblogs.com/cosyer/p/9103138.html
Copyright © 2011-2022 走看看