Using Redux in React

· 3 min read

Recently, I’ve been developing a project A, with a frontend tech stack of React+Redux. Since my React foundation was weak before (only touched a small demo), and Redux was a completely new thing, I inevitably felt constrained during development and encountered many problems. After checking official docs, searching for materials, plus actual development, I’ve gained a basic understanding, so I’m recording it here.

For Redux, those who know it say it’s simple, those who don’t say it’s difficult. Is it really difficult? Not really, let me ramble about it.

Before talking about using Redux in React, let’s chat about a few questions. Understanding these will be very beneficial for using Redux.

Why do Single Page Applications (SPA) exist?

You should know that Redux is actually born to solve state management in SPAs, so we need to think about why SPAs came into being. You know, when we used to play with jQuery, we didn’t notice needing anything like Redux, right? We can’t just use Redux because others use Redux, or use React because others use React. If it’s unnecessary from the start, why make trouble for ourselves?

推荐一文《现代 js 框架存在的根本原因》,文中给出了观点和总结。

现代前端框架主要解决 UI 与状态同步的问题

  • 现代 js 框架主要在解决 UI 与状态同步的问题。
  • 仅使用原生 js 难以写出复杂、高效、又容易维护的 UI 代码。
  • Web components 没有解决这个主要问题。
  • 虽然使用虚拟 DOM 库很容易造一个解决问题的框架,但不建议你真的这么做!

Redux能解决SPA什么问题

SPA使得前端开发更为系统,同时也带来了问题就是状态管理。Redux应运而生。 Redux官网对其进行了简介的说明

As the requirements for JavaScript single-page applications have become increasingly complicated, our code must manage more state than ever before. This state can include server responses and cached data, as well as locally created data that has not yet been persisted to the server. UI state is also increasing in complexity, as we need to manage active routes, selected tabs, spinners, pagination controls, and so on.

Managing this ever-changing state is hard. If a model can update another model, then a view can update a model, which updates another model, and this, in turn, might cause another view to update. At some point, you no longer understand what happens in your app as you have lost control over the when, why, and how of its state. When a system is opaque and non-deterministic, it’s hard to reproduce bugs or add new features.

React与Redux区别

上概念【摘自官网】

React

A JavaScript library for building user interfaces

Redux

Redux is a predictable state container for JavaScript apps

react-redux

看了以上概念,就知道,两个类库其实没关系,都是分别解决的不同层面问题,我们开发中因为会同时遇到这两个问题,所以也就存在了两者结合使用的场景—-React前端项目下需要Redux进行复杂的状态管理。

在React下使用Redux,一般使用这个类库,你可以理解为说做的React版Redux

React下Redux使用

OK,了解了大的背景及各个技术的定位目标,就可以着手开始学习了。

Redux的基础学习,建议看官网,记得反复咀嚼。

引入Redux

npm i redux --save-dev
npm i react-redux --save-dev

创建Action,Reducer,Store

Action

Reducer

Store

dispatch

具体代码直接看这里

3者之前的关系

对于Redux三大支柱有不理解的,看下图

这里解刨下

  • 组件中调用Action的执行,即store.dispatch()
  • Action发起动作,需要去给出新的reducer,所以要去计算,而计算的过程就是reducer
  • store这个概念是谁的?是redux的,React本来没有,在react的世界,一个组件身上无非就是两个东西,state,prop,state是组件当前状态,prop是父组件传递给子组件的参数。Redux的store最终会反映在组件的prop上供调用。connect的作用就是把数组store连接到目标组件上

使用辅助函数

除了本身的redux类库外,推荐增加辅助工具库来规范,优化开发体验。

redux-actions-helper

我的项目中使用了这个类库,利用辅助函数来对action 这块操作

export const initSettingAction = createAction(
  SettingActionTypes.UPDATE_SETTING,
  (inherit: ISetting, base: ISetting) => ({
    inherit,
    base
  })
);

const updateSettingReducer = (state: ISettingState, action: IAction<{ inherit: ISetting; base: ISetting }>) => ({
  ...state,
  ...action.payload
});

好处如下

  1. 利用函数强制了action中的参数与type不同级,这点也严格遵守了flux一开始制定的标准,所有的参数都在payload节点下,payload与type同级。
  2. IAction类型定义,确保了action这块的类型安全

Redux Toolkit

官方现在推出了工具包,新项目可以考虑这个。

戳这里

写在最后

到此应该基础了解差不多了,文章深度没有,多是基础,毕竟内功才王道,知其所以然,剩下的只是熟练的事了。

参考文档