0

0

Pastate.js 响应式 react 框架之 模块化

不言

不言

发布时间:2018-04-10 16:34:45

|

1805人浏览过

|

来源于php中文网

原创

本篇文章给大家分享的内容是关于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) 学生板块

  • 获取并显示学生信息

Pastate.js 响应式 react 框架之 模块化

  • 修改学生信息

Pastate.js 响应式 react 框架之 模块化

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

Pastate.js 响应式 react 框架之 模块化

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

模块划分

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

  1. 导航模块: Navigator

Pastate.js 响应式 react 框架之 模块化

  1. 学生信息模块: StudentPanel

Pastate.js 响应式 react 框架之 模块化

  1. 课程信息模块: ClassPanel

Pastate.js 响应式 react 框架之 模块化

pastate 模块构成

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

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

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

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

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

Pastate.js 响应式 react 框架之 模块化

模块结构

我们通过一个文件夹组织一个模块,以 “学生信息模块” 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 的 “选择” 方法而非直接输入字符串,这可以为应用的开发带来方便并减少无畏的错误:赋值时把输入光标在等号后的引号中间按下 “触发提示” 快捷键即可显示选项:

Pastate.js 响应式 react 框架之 模块化

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 中进行管理:

KesionEshop 在线商城系统 X1.0.150526(utf-8)
KesionEshop 在线商城系统 X1.0.150526(utf-8)

KesionCMS是漳州科兴信息技术有限公司开发的一套万能建站产品,是CMS行业最流行的网站建设解决方案之一。最新版X1.0把主系统及一些辅助系统模块化开发,前后台UI采用HTML5全新架构,方便随时删除(隐藏)安装所需要的模块。应广大用户群体建议,此次版本改动所有涉及编辑器和视频播放的模块,全部采用百度编辑器(ueditor)及ckplayer视频播放器,改进后的视频(flv,mp4等格式视频)

下载

StudentPanel.model.js

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

在初步的  actions 声明阶段,我们只需把 actions 的名字和参数声明出来,在应用开发过程中再逐渐实现其业务逻辑。你可以考虑使用 jsDoc 对 action 的用途和参数进行注释说明。当模块简单的时候,你可以直接在 actions 中直接实现同步更新 state 的操作和异步从后台获取数据等操作,pastate 不对 actions 的实现的内容做限制,不需要像 redux 或 vuex 一样规定一定要把同步和异步逻辑的分开实现,在 pastate 中,当你认为有必要时才那样做就好了。

多级 actions  管理: 当模块的 actions 比较多的时候,我们可以采用多级属性的模式对 actions 进行分类管理, 具体的分类方法和分类级别根据具体需要自行定义即可,如下:

const actions = {
    init(){ },
    handle:{
        handleBtnClick(){ },
        handleXxx1(){ },
        handleXxx2(){ }
    },
    ajax:{
        getStudentsData(){ },
        getXxx(){ },
        postXxx(data){ }
    }
}

mutations 模式:  如果你的模块比较复杂,想遵循 redux 或 vuex 把对 state 同步操作  和 异步动作两类操作分类管理的模式,那么你可以对 state 的同步操作放在 actions.mutations 分类下,pastate 提供特殊中间件对 mutations 提供而外的开发调试支持,详见 规模化 章节。

const actions = {
    init(){ },
    handleBtnClick(){ },
    getStudentsData(){ },
    mutations:{
        increaseAge(){ },
        decreaseAge(){ }
    }
}

Mutations 其实就是一些同步的 state 更新函数,你可以通过其他普通 actions 调用 mutations, 或直接在视图中调用 mutations。比起 redux dispatch actions to reducers 和 vuex commit mutations 通过字符串 mutations 名称发起(dispatch) 的模式,这种函数调用的方式在开发时更加方便且不易出错:

  • 无需为了调用方便,定义 actions / mutation 的常量名称

  • 可以友好的支持 编辑器/ IDE 的智能提示

Pastate.js 响应式 react 框架之 模块化

如果你选择使用 pastate 的 mutations 机制,  那么每个 mutation 都要使用同步函数,不要在 mutation 中使用 ajax 请求或 setTimeout 或 Promise 等异步操作。这样相关的浏览器 devtools 才能够显示 有准确意义 的信息:

Pastate.js 响应式 react 框架之 模块化

这种 actions 分类管理的设计体现了 pastate 的精益原则:你能在需要某些高级特性的时候 才去能够 使用这些高级特性。

(3)创建并配置模块的 store

我们可以像之前那样简单地创建 store:
StudentPanel.model.js

import { Pastore } from 'pastate'
const initState = {...}
const actions = {...}
...

const store = new Pastore(initState);
/** @type {initState} */
let state = store.state;

export { initState, actions, store}

Pastate 采用一种 可选的 的 actions 注入模式,你可以自愿决定是否把 actions 注入 store。 把 actions 注入 store 后,可利用 pastate 的中间件机制对 actions 进行统一管理控制,具有较强的可扩展性。例如我们可以使用 logActions 中间件对每次 actions 的调用在控制台进行 log,并使用  dispalyActionNamesInReduxTool 中间件 对把 mutations 名称显示出来,以便于调试:

import { ..., logActions, dispalyActionNamesInReduxTool } from 'pastate'

...
const store = new Pastore(initState);
store.name = 'StudentPanel';
store.actionMiddlewares = [logActions(), dispalyActionNamesInReduxTool(true)]
store.actions = actions;

/** @type {initState} */
let state = store.state;

export { initState, actions, store}

如果你觉得上面的定义方式比较琐碎,你可以直接使用 pastate 提供的工厂函数 createStore 来定义一个完整地 store:

import { ..., createStore, logActions, dispalyActionNamesInReduxTool } from 'pastate'

const store = createStore({
    name: 'StudentPanel',
    initState: initState,
    actions: actions,
    middlewares: [logActions(), dispalyActionNamesInReduxTool(true)]
})
const { state } = store // createStore 具有良好的泛型定义,无需额外的 jsdoc 注释即可获取 state 的结构信息

你也可以进一步把中间件配置为仅在开发环境下生效的模式, 生产环境下无效。Pastate 中间件的详细内容请查看规模化章节。

视图部分

我们创建 StudentPanel.view.jsx 文件来保存我们的模块视图, 视图定义和原来的模式类似:
StudentPanel.view.jsx

import React from 'react'
import { makeContainer, Input, Select} from 'pastate'
import { initState, actions } from './StudentPanel.model'
import './StudentPanel.css'

const isBoyOptions = [{
    value: true,
    tag: '男'
},{
    value: false,
    tag: '女'
}]

class StudentPanel extends React.PureComponent {

    componentDidMount(){
        actions.init()
    }

    render() {
        let state = this.props.state
        return (
            <p className="info-panel">
                {this['view_' + state.status](state)}
            </p>
        )
    }

    view_loading() {
        return (
            <p className="info-panel-tip-loading">
                加载中...
            </p>
        )
    }

    view_error() {
        return (
            <p className="info-panel-tip-error">
                加载失败, 请刷新重试
            </p>
        )
    }

    /** @param {initState} state */
    view_ok(state) {
        let selectedStudent = state.students[state.selected];
        return (
            <p className="info-panel-ok">
                ...
            </p>
        )
    }
}

export default makeContainer(StudentPanel)

Pastate 模块化需要实现一种多模块可以互相协作的机制。因此我们不再使用 makeOnyContainer 唯一地绑定一个视图组件与对应的 store。首先,我们会用各模块的 store 生成一个全局的 store 树,并使用 makeContainer 把模块的视图封装为引用全局 store 的某些节点的容器。

我们目前只有一个模块,此处简单地调用 makeContainer(StudentPanel)  让 StudentPanel 引用全局的 store 树 的根节点的 state ,我们可以为 makeContainer 指定第二个参数,指明引用 store 树 的哪些子节点,详情会在下一章介绍。

在上面视图组件的代码中,我们引入了 model 中的 actions:

import { store, initState, actions } from './StudentPanel.model'

这些 actions 可以直接赋值到组件的 onClick 或 onChange 等位置:

<button className="..." onClick={actions.increaseAge} > + </button>

这些 actions 也可以在组件的生命周期函数中调用:

...
componentDidMount(){
    actions.init()
}
...

视图部分还包含样式文件 StudentPanel.css ,在此就不列出了。

如果该模块要需要封装一些当前模块专用的子组件,把子组件定义为独立的文件,并放在与 StudentPanel 模块相同的文件夹下即可。如果需要封装一些多个模块通用的非容器组件,可以考虑把它们放在独立于模块文件夹的其他目录。

导出模块

最后,为了方便调用,我们来为模块做一个封装文件 StudentPanel / index.js,导出模块的元素:

export { default as view } from './StudentPanel.view'
export { store, actions, initState } from './StudentPanel.model'

pastate 模块向外导出 view, initState, actions, store 四个元素。

大功告成!这时我们可以尝试在 src / index.js 中引入该模块并渲染出来:

import ReactDOM from 'react-dom';
import { makeApp } from 'pastate';
import * as StudentPanel from './StudentPanel';

ReactDOM.render(
    makeApp(<StudentPanel.view />, StudentPanel.store), 
    document.getElementById('root')
);
...

我们使用 makeApp 函数创建一个 pastate 应用并渲染出来,makeApp 的第一个参数是 根容器,第二个参数是 store 树, 我们现在只有一个模块,所以应用的 store 树只有 StudentPanel 的 store。

自此,我们的第一个模块 StudentPanel 构建完成。

模块的模板文件

我们可以使用模板文件快速创建模块,一个模块的模板文件非常简单,下面以 TemplateModule 模块为例完整给出:

  • /index.js

export { default as view } from './TemplateModule.view'
export { initState, actions, store } from './TemplateModule.model'
  • /TemplateModule.model.js

import { createStore } from 'pastate';

const initState = {

}

const actions = {

}

const store = createStore({
    name: 'TemplateModule',
    initState,
    actions
})
const { state } = store
export { initState, actions, store }
  • /TemplateModule.view.jsx

import React from 'react';
import { makeContainer } from 'pastate';
import { initState, actions } from './ClassPanel.model';
import './TemplateModule.css'

class TemplateModule extends React.PureComponent{
    render(){
        /** @type {initState} */
        const state = this.props.state;
        return (
            <p>
                TemplateModule
            </p>
        )
    }
}

export default makeContainer(TemplateModule, 'template')
  • /.css

// css 样式文件初始为空,你也可以选用 less 或 sass 来定义样式

这个例子的 demo 源码已包含该模板模块 src/TemplateModule, 你只需把它复制到你的 src 目录下,并右键点击模块文件夹,选择 “在文件夹中查找”,然后把 TemplateModule 字符串全部替换为你想要的模块名称即可:

Pastate.js 响应式 react 框架之 模块化

Pastate.js 响应式 react 框架之 模块化

点击替换之后保存文件。不过目前还不能自动替换文件名,需要手动替换一下。

Pastate 以后将会实现相关的命令行工具,实现一行命令创建新模块等功能,加速 pastate 应用的开发。

下一章,我们来创建另外的模块,并介绍不同模块之间如何协作。

相关推荐:

Pastate.js 响应式框架之数组渲染与操作

Pastate.js 响应式 react 框架之表单渲染与操作

Pastate.js 响应式框架之多组件应用

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

463

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

135

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

64

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

26

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

14

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

524

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

53

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 5.2万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 3万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号