从 Flux 到 Redux:一个严谨的状态管理方案演进之路

从 Flux 到 Redux:一个严谨的状态管理方案演进之路

在前端开发中,状态管理是一个至关重要的概念。状态管理可以让前端应用更容易维护和扩展。在过去的几年间,Flux 和 Redux 凭借着其强大的状态管理能力成为了前端领域的热门技术。本文将从 Flux 的设计缺陷讲起,深入探讨 Flux 和 Redux 的架构设计,解决问题,并对其进行实例代码的演示。

Flux的设计缺陷

Flux 是 Facebook 推出的状态管理框架,它的核心思想是数据的单向流动,即视图的变化只能通过修改数据来实现。在 Flux 的架构中,有四个核心概念:

  • Store:存储数据的容器
  • Action:表示用户操作
  • Dispatcher:负责将 Action 分发给 Store
  • View:展示界面

然而,Flux 的架构存在一个设计缺陷:Store 之间的依赖十分复杂。在 Flux 中,各个 Store 都是独立的,但是实际上,我们常常需要一个 Store 依赖于另一个 Store。这种情况下,Store 之间的相互影响会使得代码难以维护,因为不同的操作可能会影响到多个 Store。

此外,在 Flux 中,每个 Action 都需要显式地调用 Dispatcher。这种做法在代码中增加了额外的复杂度,使得代码难以理解。

Redux的优势与架构设计

为了解决 Flux 中存在的这些问题,Redux 应运而生。Redux 的设计思想是将所有的状态统一放在一个 Store 中进行管理,这个 Store 是唯一的,整个应用共享。

Redux 的架构中有三个核心概念:

  • Action:视图层的数据流操作
  • Reducer:更新 Store 中的数据
  • Store:应用的状态管理中心

所有的数据流都必须围绕 Actions 发生。一个 Action 是一个纯 JavaScript 对象,用于描述一个用户操作改变了应用的状态。Reducer 是一个纯 JavaScript 函数,它负责接收应用的当前状态(或 Store)和一个 Action 对象,之后计算出一个新的状态。

Store 是 Redux 的状态管理中心,它通过 Reducer 处理传入的 Action,更新应用的状态。

相对于 Flux 的架构,Redux 的设计更为优美和精简。Reduce 函数的纯函数特性,保证状态变更逻辑的严格性和一致性;Store 对于状态的异步更新以及状态复杂度更高情况下的处理,更加合理明确地得到表达。这样做可以更好的维护和修改应用程序。

Redux的实例代码演示

下面我们通过将 Redux 应用于一个用户表单的案例来示范 Redux 中的设计思想和实践。

引入Redux

在 React 项目中使用 Redux,需要先安装依赖:

npm install --save redux react-redux

定义Action

在实现过程中,用户表单涉及到用户基本信息的输入、提交等操作。那么,这些操作均需要体现在一个 Action 中。

const setUserBasicInfo = (name, age) => ({
  type: "SET_USER_BASIC_INFO",
  payload: { name, age }
});
const submitUserForm = () => ({ type: "SUBMIT_USER_FORM" });

定义Reducer

在 Redux 中,我们需要定义一个纯函数作为 Reducer,该函数接收当前状态和 Action 作为参数,计算出新的状态并返回。

const initialState = {
  name: "",
  age: 0,
  submitting: false,
  submitted: false
};
const userFormReducer = (state = initialState, action) => {
  switch (action.type) {
    case "SET_USER_BASIC_INFO": {
      const { name, age } = action.payload;
      return { ...state, name, age };
    }
    case "SUBMIT_USER_FORM": {
      return { ...state, submitting: true };
    }
    case "SUBMIT_USER_FORM_SUCCESS": {
      return { ...state, submitting: false, submitted: true };
    }
    case "SUBMIT_USER_FORM_FAILURE": {
      return { ...state, submitting: false, submitted: false };
    }
    default:
      return state;
  }
};

定义Store

在定义 Store 时,我们需要引入 Redux 的 createStore 方法、Reducer、中间件等。

import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import userFormReducer from "./reducers/userFormReducer";

const store = createStore(userFormReducer, applyMiddleware(thunk));

渲染视图

在组件的事件处理函数中,发出了相应的 Action。在 Redux 中,我们需要使用 connect 方法将 React 组件和 Redux 关联起来。

import React from "react";
import { connect, Provider } from "react-redux";
import {
  setUserBasicInfo,
  submitUserForm,
} from "../store/actions/userFormActions";
import store from "../store";

class UserForm extends React.Component {
  handleSubmit = () => {
    this.props.submitUserForm();
  };
  handleInputChange = (e) => {
    const { name, value } = e.target;
    this.props.setUserBasicInfo(name, value);
  };
  render() {
    const { name, age, submitting, submitted } = this.props;
    return (
      <form>
        <input
          type="text"
          name="name"
          value={name}
          onChange={this.handleInputChange}
        />
        <br />
        <input
          type="number"
          name="age"
          value={age}
          onChange={this.handleInputChange}
        />
        <br />
        <button type="button" onClick={this.handleSubmit}>
          Submit
        </button>
        {submitting && <span>Submitting...</span>}
        {submitted && <span>Submitted successfully!</span>}
      </form>
    );
  }
}

const mapStateToProps = (state) => ({
  name: state.name,
  age: state.age,
  submitting: state.submitting,
  submitted: state.submitted,
});

const mapDispatchToProps = (dispatch) => ({
  setUserBasicInfo: (name, age) => dispatch(setUserBasicInfo(name, age)),
  submitUserForm: () => dispatch(submitUserForm()),
});

const ConnectedUserForm = connect(
  mapStateToProps,
  mapDispatchToProps
)(UserForm);

const App = () => (
  <Provider store={store}>
    <ConnectedUserForm />
  </Provider>
);

export default App;

总结

本文介绍了 Redux 的架构设计和应用实践,讲述了 Flux 的设计缺陷以及如何通过 Redux 优化状态管理的方式,使应用状态更加严谨和易于维护。Redux 不但有非常优雅的设计思路,而且还能在实际项目中发挥重要作用,提高代码质量,加快开发效率。希望本文能给各位开发者提供一些指导意义,以便更好地使用 Redux 进行开发。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65b9a886add4f0e0ff22831c