📜  JavaScript 架构 Flux 组件(1)

📅  最后修改于: 2023-12-03 15:01:44.852000             🧑  作者: Mango

JavaScript 架构 Flux 组件

什么是 Flux

Flux 是一种用于构建用户界面的架构模式,由 Facebook 提出。它强调单向数据流,使得应用程序的数据更易于理解并且容易调试。

Flux 的核心概念

Flux 架构图如下所示:

Flux 架构图

从图中可以看出 Flux 架构有四个核心概念:

  1. Action:描述了用户在视图上执行的操作,例如点击按钮、输入内容等。
  2. Dispatcher:负责将 Action 分发到 Store。
  3. Store:负责存储应用程序的状态并响应 Dispatcher 分发的 Action。
  4. View:展示最终结果的用户界面。
Flux 组件的实现

我们可以使用 React 框架来实现 Flux 架构中的组件。使用 React 时,我们通常使用 Flux 的原始实现 —— Flux,或者 Redux

Flux

Flux 是 Facebook 官方的架构实现,包含了 Dispatcher、Store 和 Action Creator 的实现。

其中,Action Creator 用来封装创建 Action 的逻辑。例如:

var AppActions = {
  createItem: function (text) {
    AppDispatcher.dispatch({
      actionType: ActionTypes.CREATE_ITEM,
      text: text
    });
  },

  deleteItem: function (id) {
    AppDispatcher.dispatch({
      actionType: ActionTypes.DELETE_ITEM,
      id: id
    });
  },

  ...
};

Dispatcher 是 Flux 架构的核心,负责在 Store 之间传递 Action。它提供了两个方法:register()dispatch()。例如:

var AppDispatcher = new Dispatcher();

AppDispatcher.register(function (payload) {
  switch (payload.actionType) {
    case ActionTypes.CREATE_ITEM:
      ItemStore.create(payload.text);
      ItemStore.emitChange();
      break;

    case ActionTypes.DELETE_ITEM:
      ItemStore.delete(payload.id);
      ItemStore.emitChange();
      break;

    ...
  }
});

Store 中存储应用程序状态,响应 Dispatcher 分发的 Action。它提供了事件监听函数 addListener()removeListener(),以及获取数据状态的方法 getData()

var EventEmitter = require('events').EventEmitter;

var _data = [];

function create(text) {
  _data.push(text);
}

function delete(id) {
  var index = _data.indexOf(id);
  _data.splice(index, 1);
}

var ItemStore = assign({}, EventEmitter.prototype, {
  getAll: function () {
    return _data;
  },

  emitChange: function () {
    this.emit('change');
  },

  addChangeListener: function (callback) {
    this.on('change', callback);
  },

  removeChangeListener: function (callback) {
    this.removeListener('change', callback);
  },

  dispatcherIndex: AppDispatcher.register(function (payload) {
    var actionType = payload.actionType;
    var text = payload.text;
    var id = payload.id;

    switch (actionType) {
      case ActionTypes.CREATE_ITEM:
        create(text);
        ItemStore.emitChange();
        break;

      case ActionTypes.DELETE_ITEM:
        delete(id);
        ItemStore.emitChange();
        break;

      ...
    }
  })
});

View 负责展现最终结果的用户界面,使用 Store 中的数据状态渲染。例如:

var ItemList = React.createClass({
  getInitialState: function () {
    return {
      items: ItemStore.getAll()
    };
  },

  componentDidMount: function () {
    ItemStore.addChangeListener(this._onChange);
  },

  componentWillUnmount: function () {
    ItemStore.removeChangeListener(this._onChange);
  },

  render: function () {
    var items = this.state.items.map(function (item) {
      return (
        <li>{item}</li>
      );
    });

    return (
      <ul>{items}</ul>
    );
  },

  _onChange: function () {
    this.setState({
      items: ItemStore.getAll()
    });
  }
});
Redux

Redux 是一种更为简化和易用的 Flux 实现,利用单一存储对象、纯函数(reducer)和函数式思想改进了 Flux 的原始实现,被广泛使用。

在 Redux 中,通过 Action Creator 创建 Action 对象,并通过 store.dispatch() 方法将它们派发到 Store。Store 就是应用的状态管理器,存储着应用的状态,并响应 Dispatcher 分发的操作。在 Redux 中,Store 不是单独存在的,而是被 Store Creator 创建出来。同时和 Store 相关,Reducer 成了 Redux 中的新概念。它负责处理 Dispatch 加载到 Store 中的各种 Action 信息。例如:

const reducer = (state = [], action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'TOGGLE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: !todo.completed
          })
        }
        return todo
      })
    case 'SET_VISIBILITY_FILTER':
      return {
        ...state,
        visibilityFilter: action.filter
      }
    default:
      return state
  }
}

同时,Redux 中需要使用 connect() 方法把组件和 Redux 关联在一起,使得组件能够访问 Store 中的状态信息,以及 Dispatch 相关的操纵方法。例如:

import { connect } from 'react-redux'

const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)
结论

Flux 架构采用单向数据流的模式,使得数据流向更加清晰,更加容易被理解和调试。同时,Flux 在 React 中的实现,为开发者实现了单向数据流的自动化,使得开发者可以专注于代码的编写,而不必过多考虑数据的传递和状态的管理。而 Redux 更为简化和易用,得到了广泛的认可和支持,在前端开发领域取得了极大的成功。