本篇文章给大家分享的内容是关于Pastate.js 响应式 react 框架之 模块化 ,有着一定的参考价值,有需要的朋友可以参考一下

这是 Pastate.js 响应式 react state 管理框架系列教程,欢迎关注,持续更新。

Pastate.js Github

模块化实战任务

如果应用比较复杂,有很多个页面,且一个界面具有比较多的组件和操作时,我们需要对应用划分模块 (Module) 进行管理。
下面我们以一个 班级信息管理系统 为例,介绍 pastate 应用的模块化机制。

实际体验:https://birdleescut.github.io/pastate-demo

应用源码: https://github.com/BirdLeeSCUT/pastate-demo

应用的原型如下:

(1) 学生板块

获取并显示学生信息

修改学生信息

(2) 课程板块: 显示课程信息

这个应用相对比较简单,在实际开发中我们不一定需要对其进行模块化设计,在此我们只是用于介绍 pastate 模块化机制,让你知道如何用 pastate 处理足够复杂的应用。

模块划分

模块化设计的第一步就是模块划分,我们先从对我们的班级信息管理系统进行模块划分:

导航模块: Navigator

学生信息模块: StudentPanel

课程信息模块: ClassPanel

pastate 模块构成

pastate 的模块机制是一种简洁的 flux 模式实现,一个 pastate 模块由三个基本元素构成:

状态 (state):保存模块当前的状态

视图 (view):模块状态的显示逻辑

动作 (action):模块动作的处理逻辑

这三个模块元素遵循如下的单向数据流过程:

模块结构

我们通过一个文件夹组织一个模块,以 “学生信息模块” StudentPanel 为例,新建一个 StudentPanel 文件夹,并在文件夹下创建以下文件:

StudentPanel 模块文件夹

StudentPanel.model.js 模型文件:用于定义应用的 state 和 actions

StudentPanel.view.jsx 视图文件:用于定义的视图组件(组件渲染逻辑)

StudentPanel.css 样式文件:用于定义用于的样式(可以改用 less 或 sass)

模型文件 *.model.js(1)设计模块的 state

我们先在模型文件 StudentPanel.model.js 下定义模块的 state 结构:
StudentPanel.model.js

const initState = { initialized: false, // 初始化状态 /** @type { "loading" | "ok" | "error" } */ status: 'loading', // 加载状态 isEditting: false, // 是否在编辑中 selected: 0, // 选中的学生 /** @type {studentType[]} */ students: [] // 学生数组 } const studentType = { name: '张小明', studentNumber: '2018123265323', age: 22, isBoy: true, introduction: '我是简介' } ...

与之前一样,我们通过配合 jsDoc 注释,把 state 结构的定义和初始值得定义一起进行。

Tips: 建议使用上面定义 status 属性的模式定义 “枚举字符串” 类型,对这种枚举值进行赋值时尽量采用 intelSence 的 “选择” 方法而非直接输入字符串,这可以为应用的开发带来方便并减少无畏的错误:赋值时把输入光标在等号后的引号中间按下 “触发提示” 快捷键即可显示选项:

State mock 区域: 我们在开发视图时,需要对 state 的状态进行完备测试,比如要让 state.status 分别等于 "loading" | "ok" | "error" 、让 state.isEditting 等于 true | false 去完备地测试模块的渲染逻辑,这时我们不要直接更改 initState 的值,而是把 initState 下方作为一个 state mock 测试区域, 对 state 进行修改以实现 mock :

const initState = {...} const studentType ={...} /***** MOCK AREA *****/ // initState.status = 'ok' // initState.isEditting = true // initState.students = [studentType, studentType]

你可以根据开发调试需求新建 mock 行,或通过注释控制某个 mock 行是否生效,以此来使应用处于某个中间 state 状态,方便调试。并在模块开发完成时把 mock 区域全部注释即可,这种模式可以有效地管理 mock 过程。

模块的 initState 是对模块的一种 “定义”,它具有“文档属性”,而 mock state 是对应用进行调试时执行的临时动态操作,如果通过直接修改 initState 来进行 mock,我们会破坏模块的定义,然后又尝试凭记忆对定义进行恢复,这个过程容易出错或遗漏,特别是当 state 变得复杂的时候。所以我们推荐采用 MOCK AREA 对 state 进行 mock 调试。

(2)定义模块的 actions

之前我们是把应用的动作逻辑实现为视图组件的成员函数,在应用简单时这种模式会比较直接方便,而当应用复杂且某些操作逻辑需要在不同组件甚至模块间共享时,原理的模式无法实现。因此我们把模块的相关操作逻辑统一放在 actions 中进行管理:

StudentPanel.model.js

const actions = { init(){ }, loadStudents(){ }, switchEditting(){ }, /** @param {number} index 学生数组索引号 */ selectStudent(index){ }, increaseAge(){ }, decreaseAge(){ } }