前端状态管理与有限状态机

这篇具有很好参考价值的文章主要介绍了前端状态管理与有限状态机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

当下前端流行的框架,都是用状态来描述界面(state => view),可以说前端开发实际上就是在维护各种状态(state),这已经成为目前前端开发的共识。

 

复制代码

View = ViewModel(Model);

理想情况下,ViewModel 是纯函数,给定相同的 Model,产出相同的 View。

state => view 很好理解,但如何在 view 中合理地修改 state 也是一个问题。

为什么需要状态管理

举个例子

图书馆的管理,原来是开放式的,所有人可以随意进出书库借书还书,如果人数不多,这种方式可以减少流程,增加效率,一旦人数变多就势必造成混乱。

Flux 就像是给这个图书馆加上了一个管理员,所有借书还书的行为都需要委托管理员去做,管理员会规范对书库的操作行为,也会记录每个人的操作,减少混乱的现象。

一个比喻

我们寄一件东西的过程

没有快递时:

  • 打包准备好要送出去的东西
  • 直接到朋友家,把东西送给朋友
  • 很直接很方便,很费时间

有了快递公司:

  • 打包准备好要送出去的东西
  • 到快递公司,填写物品,收件人等基本信息
  • 快递公司替你送物品到你的朋友家,我们的工作结束了

多了快递公司,让快递公司给我们送快递。

当我们只寄送物品给一个朋友,次数较少,物品又较少的时候,我们直接去朋友家就挺好的。但当我们要频繁寄送给很多朋友很多商品的时候,问题就复杂了。

软件工程的本质即是管理复杂度。使用状态管理类框架会有一定的学习成本而且通常会把简单的事情做复杂,但如果我们想做复杂一点的事情(同时寄很多物品到多个不同地址),对我们来说,快递会让复杂的事情变的简单。

这同时也解释了,是否需要添加状态管理框架,我们可以根据自己的业务实际情况和技术团队的偏好而添加,有些情况下,创建一个全局对象就能解决很多问题。

核心思想

Flux 的核心思想:数据单向流动。

  • 不同组件的 state,存放在一个外部的、公共的 Store 上面。
  • 组件订阅 Store 的不同部分。
  • 组件发送(dispatch)动作(action),引发 Store 的更新。

Redux 的核心概念

  • 所有的状态存放在 Store。组件每次重新渲染,都必须由状态变化引起。
  • 用户在 UI 上发出 action。
  • reducer 函数接收 action,然后根据当前的 state,计算出新的 state。

Redux store 是单一数据源。Redux 没有 dispatcher 的概念,转而使用纯函数(pure function)代替。

Redux store 是不可变的(Immutable)。

MobX

  • Observable:它的 state 是可被观察的,无论是基本数据类型还是引用数据类型,都可以使用 MobX 的 (@)observable 来转变为 observable value。
  • Reactions:它包含不同的概念,基于被观察数据的更新导致某个计算值(computed values),或者是发送网络请求以及更新视图等,都属于响应的范畴,这也是响应式编程(Reactive Programming)在 JavaScript 中的一个应用。
  • Actions:它相当于所有响应的源头,例如用户在视图上的操作,或是某个网络请求的响应导致的被观察数据的变更。

和 Redux 对单向数据流的严格规范不同,Mobx 只专注于从 store 到 view 的过程。在 Redux 中,数据的变更需要监听,而 Mobx 的数据依赖是基于运行时的,这点和 Vuex 更为接近。

Vuex 的状态管理模式

  • state,驱动应用的数据源;
  • view,以声明方式将 state 映射到视图;
  • actions,响应在 view 上的用户输入导致的状态变化。

Flux

Facebook 提出了 Flux 架构思想,规范了数据在应用中的流动方式。其基本架构如下入所示,其核心理念是单向数据流,它完善了 React 对应用状态的管理。

前端状态管理与有限状态机,前端,javascript,开发语言

 

上图描述了页面的启动和运行原理:

1.通过 dispatcher 派发 action,并利用 store 中的 action 处理逻辑更新状态和 view

2.而 view 也可以触发新的 action,从而进入新的步骤 1

其中的 action 是用于描述动作的简单对象,通常通过用户对 view 的操作产生,包括动作类型和动作所携带的所需参数,比如描述删除列表项的 action:

 

复制代码

{ type: types.DELETE_ITEM, id: id };

而 dispatcher 用于对 action 进行分发,分发的目标就是注册在 store 里的事件处理函数:

 

复制代码

dispatcher.register(function(action) { switch (action.type) { case "DELETE_ITEM": sotre.deleteItem(action.id); //更新状态 store.emitItemDeleted(); //通知视图更新 break; default: // no op } });

store 包含了应用的所有状态和逻辑,它有点像传统的 MVC 模型中的 model 层,但又与之有明显的区别,store 包括的是一个应用特定功能的全部状态和逻辑,它代表了应用的整个逻辑层;而不是像 Model 一样包含的是数据库中的一些记录和与之对应的逻辑。

参考链接:flux

Redux

原生 Redux API 最简单的用例

 

复制代码

function counter(state, action) { if (typeof state === "undefined") { return 0; } switch (action.type) { case "INCREMENT": return state + 1; case "DECREMENT": return state - 1; default: return state; } } var store = Redux.createStore(counter); // var valueEl = document.getElementById("value"); function render() { valueEl.innerHTML = store.getState().toString(); } render(); store.subscribe(render); document.getElementById("increment").addEventListener("click", function() { store.dispatch({ type: "INCREMENT" }); }); document.getElementById("decrement").addEventListener("click", function() { store.dispatch({ type: "DECREMENT" }); }); document.getElementById("incrementIfOdd").addEventListener("click", function() { if (store.getState() % 2 !== 0) { store.dispatch({ type: "INCREMENT" }); } }); document.getElementById("incrementAsync").addEventListener("click", function() { setTimeout(function() { store.dispatch({ type: "INCREMENT" }); }, 1000); });

应用中所有的 state 都以一个对象树的形式储存在一个单一的 store 中。 改变 state 的唯一办法是触发 action,一个描述发生什么的对象。 为了描述 action 如何改变 state 树,你需要编写 reducers。

Redux 三大原则

  • 单一数据源

    整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。

  • state 是只读的

    唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。

  • 使用纯函数来执行修改

    为了描述 action 如何改变 state tree ,你需要编写 reducers。 改变 state 的惟一方法是 dispatch action。你也可以 subscribe 监听 state 的变化,然后更新 UI。

严格的单向数据流是 Redux 架构的设计核心。

Redux API

Redux 的 API 非常少。

Redux 定义了一系列的约定(contract)来让你来实现(例如 reducers),同时提供少量辅助函数来把这些约定整合到一起。

Redux 只关心如何管理 state。在实际的项目中,你还需要使用 UI 绑定库如 react-redux。

  • createStore(reducer, [preloadedState], [enhancer])
  • combineReducers(reducers)
  • bindActionCreators(actionCreators, dispatch)
  • applyMiddleware(...middlewares)
  • compose(...functions)

immutable

在写 redux 的 action 的时候,总是需要用到扩展语句或者 Object.assign()的方式来得到一个新的 state,这一点对于 JavaScript 而言是对象的浅拷贝,它对内存的开销肯定是大于 mobX 中那样直接操作对象属性的方式大得多。

参考链接:redux-immutable seamless-immutable reselect 为什么使用 Redux 管理状态是可预测的

redux-saga

redux 是 react 技术栈中的状态控制流框架,使用了标准的函数式思想,期望(强制)所有状态管理都是纯函数。这也意味着各状态之间都是独立的。但是有一类状态 redux 直接甩给了的第三方模块,副作用模块 redux-saga 也就成了任劳任怨的典型代表。副作用正是因为不确定性和可变性而得名,而其给出的状态又是相互影响,如何解耦使得原本复杂的非线性呈现为线性逻辑,正是有限状态机的用武之处。

DvaJS

dva 首先是一个基于 reduxredux-saga 的数据流方案,然后为了简化开发体验,dva 还额外内置了 react-routerfetch,所以也可以理解为一个轻量级的应用框架。

在 redux 的生态圈内,每个环节有多种方案,比如 Data 可以是 immutable 或者 plain object,在你选了 immutable 之后,用 immutable.js 还是 seamless-immutable,以及是否用 redux-immutable 来辅助数据修改,都需要选择。

参考链接:Redux 中文文档 immutable-js immer dvajs React + Redux 最佳实践

MobX

MobX 是一个用法简单优雅、同时具有可扩展性的状态管理库。

一个简单的例子

 

复制代码

import { observable, autorun } from "mobx"; const appState = observable({ counter: 0, add(value) { this.counter += value; } }); autorun(() => console.log(appState.counter)); setInterval(() => appState.add(1), 1000);

在 mobx 中我们可以直接修改状态

 

复制代码

import { observable } from "mobx"; const appState = observable({ counter: 0 }); appState.counter += 1;

可以通过引入 Strict 模式来避免这种不良好的实践:

 

复制代码

import { useStrict } from "mobx"; useStrict(true);

MobX 脱胎于响应式编程(Reactive Programming),其核心思想为 Anything that can be derived from the application state, should be derived. Automatically,即避免任何的重复状态。

MobX 中核心的概念即是 Observable,相信接触过响应式编程的肯定非常熟悉,从后端的典型代表 RxJava 到 Android/iOS 开发中的各种响应式框架都各领风骚。

与 Redux 状态管理上的异同

Redux / MobX 均为客户端开源状态管理库,用状态来描述 UI 界面,它们与 React 都不具有强绑定关系,你也可以配合别的框架来使用它们。 当然,与 React 是再合适不过的了,React 作为 View 层的框架,通过 Virtual DOM 机制来优化 UI 渲染,Redux / MobX 则提供了将相应状态同步到 React 的机制。

Redux 与 MobX 的不同主要集中于以下几点:

  • Redux 是单一数据源,而 MobX 往往是多个 store。MobX 可以根据应用的 UI、数据或业务逻辑来组织 store,具体如何进行需要你自己进行权衡。
  • Redux store 使用普通的 JavaScript 对象结构,MobX 将常规 JavaScript 对象包裹,赋予 observable 的能力,通过隐式订阅,自动跟踪 observable 的变化。MobX 是观察引用的,在跟踪函数中(例如:computed value、reactions 等等),任何被引用的 observable 的属性都会被记录,一旦引用改变,MobX 将作出反应。注意,不在跟踪函数中的属性将不会被跟踪,在异步中访问的属性也不会被跟踪。
  • Redux 的 state 是只读的,只能通过将之前的 state 与触发的 action 结合,产生新的 state,因此是纯净的(pure)。而 MobX 的 state 即可读又可写,action 是非必须的,可以直接赋值改变,因此是不纯净的(Impure)。
  • Redux 需要你去规范化你的 state,Immutable 数据使 Reducer 在更新时需要将状态树的祖先数据进行复制和更新,新的对象会导致与之 connect 的所有 UI 组件都重复渲染。因此 Redux state 不建议进行深层嵌套,或者需要我们在组件中用 shouldComponentUpdate 优化。而 MobX 只自动更新你所关心的,不必担心嵌套带来的重渲染问题。
  • 在 Redux 中区分有 smart 组件与 dumb 组件,dumb 负责展示,smart 负责状态更新,数据获取。而在 MobX 中无需区分,都是 smart,当组件自身依赖的 observable 发生变化时,会作出响应。

Mobx 思想的实现原理

Mobx 最关键的函数在于 autoRun,autoRun 的专业名词叫做依赖收集,也就是通过自然的使用,来收集依赖,当变量改变时,根据收集的依赖来判断是否需要更新。Mobx 使用了 Object.defineProperty 拦截 getter 和 setter,和 Vue 一样。

参考链接: mobx MobX 中文文档

Vuex

Vuex 是专门为 Vue.js 设计的状态管理库。把组件的共享状态抽取出来,以一个全局单例模式管理。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

核心概念

  • State
  • Getter
  • Mutation
  • Action
  • Module

API

Vuex 的用法很简单,  一句话总结:commit mutation,dispatch action

前端状态管理与有限状态机,前端,javascript,开发语言

 

参考链接:Vuex 官方文档

有限状态机(FSM)

前端状态管理与有限状态机,前端,javascript,开发语言

 

有限状态机(finite-state machine)又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型,非常有用,可以模拟世界上大部分事物。

有限状态机并不是一个复杂的概念,简单说,它有三个特征:

  • 状态总数(state)是有限的。
  • 任一时刻,只处在一种状态之中。
  • 某种条件下,会从一种状态转变(transition)到另一种状态。

总结

使用状态去影响视图,而 Action 主要负责完成状态间的变更。代码如何更好的构建其核心在于使用最合理的状态去管理界面,并用最合理的动作去实现状态间的变更。

所谓的状态管理,实际上就是使用有限状态机来管理前端状态。

有限状态机对 JavaScript 的意义在于,很多对象可以写成有限状态机。

写代码之前,思考一下:

  • 页面有几种状态(初始化状态?成功状态?失败状态?出错状态?)。
  • 描述这些状态需要什么参数。
  • 在什么时候转变状态,需要改变哪些部分。

然后跟着思路,完成数据与 UI 部分。

参考链接:javascript-state-machine xstate managing-state-in-javascript-with-state-machines-stent文章来源地址https://www.toymoban.com/news/detail-839965.html

到了这里,关于前端状态管理与有限状态机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • HarmonyOS学习路之方舟开发框架—学习ArkTS语言(状态管理 六)

    AppStorage是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。 和LocalStorage不同的是,LocalStorage是页面级的,通常应用于页面内的数据共享。而对于AppStorage,是应用级的全局状态共享。 AppStorage是在应用启动

    2024年02月20日
    浏览(51)
  • 大型医院云HIS系统:采用前后端分离架构,前端由Angular语言、JavaScript开发;后端使用Java语言开发 融合B/S版电子病历系统

    一套医院云his系统源码 采用前后端分离架构,前端由Angular语言、JavaScript开发;后端使用Java语言开发。融合B/S版电子病历系统,支持电子病历四级,HIS与电子病历系统均拥有自主知识产权。 文末卡片获取联系! 基于云计算技术的B/S架构的医院管理系统(简称云HIS),采用前后

    2024年02月03日
    浏览(48)
  • 【尚医通】vue3+ts前端项目开发笔记 2 —— 创建项目、封装网络请求、集成elment-plus 、重置样式、准备状态管理/路由 等开发前准备

    服务器地址:http://syt.atguigu.cn 医院接口:http://139.198.34.216:8201/swagger-ui.html 公共数据接口:http://139.198.34.216:8202/swagger-ui.html 会员接口:http://139.198.34.216:8203/swagger-ui.html 短信验证码接口:http://139.198.34.216:8204/swagger-ui.html 订单接口:http://139.198.34.216:8206/swagger-ui.html 文件上传接口:

    2024年02月13日
    浏览(49)
  • Unity有限状态机

    一、引言 在游戏开发中,经常会遇到游戏角色或实体具有多种状态,并且在不同状态之间需要切换的情况。例如,一个角色可能处于行走、奔跑、跳跃等不同的状态,并且根据玩家的输入或游戏逻辑,在这些状态之间进行切换。为了管理这些状态及其之间的转换,我们可以使

    2024年02月03日
    浏览(50)
  • 有限状态机(FSM)

    目录 一、什么是有限状态机 二、如何实现 1、简述原理 2、 具体实现 有限状态机就是一种用来描述对象不同状态之间如何相互转换的模型,这里最简单的例子就是动画状态机 animator 我们每一次都只能处于一个状态,每一个状态又可以通过一定的条件相互转换。 1、简述原理

    2024年02月11日
    浏览(43)
  • 编译原理二:有限状态机

    有限状态机是一种 计算模型 ,它可以 接受一串输入并根据一组状态转移规则进行状态转移,最终输出一个结果 。有限状态机可以分为两种类型: 确定性有限状态机(DFA) 和 非确定性有限状态机(NFA) 。 DFA 是一种状态机,它的 每个状态都有一条出边对应每个输入符号,

    2024年02月11日
    浏览(37)
  • 12-同步状态机的结构以及Mealy和Moore状态机的区别,Verilog实现有限状态机的4种方式,以及总结有限状态机设计的一般步骤

    由于寄存器传输级(RTL)描述的是以时序逻辑抽象所得到的有限状态机为依据,因此,把一个时序逻辑抽象成一个同步有限状态机是设计可综合风格的Verilog HDL模块的关键。 在本章节中,在了解状态机结构的基础上通过各种实例,由浅入深地介绍各种可综合风格的Verilog HDL模

    2024年01月17日
    浏览(46)
  • 探索FSM (有限状态机)应用

    我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。。 本文作者:木杪 有限状态机(FSM) 是计算机科学中的一种数学模型,可用于表示和控制系统的行为。它由一组状态以及定义在这些

    2023年04月20日
    浏览(34)
  • 【FPGA入门】第四篇、有限状态机

    目录 第一部分、一个关于有限状态机的例子 第二部分、学会有限状态机的准备知识 1、什么是有限状态机? 2、为什么需要状态机? 3、什么是竞争冒险? 3.1、什么情况下会发生竞争冒险? 3.2、为什么组合逻辑电路会产生竞争和冒险? 3.3、那什么是竞争?什么是冒险? 3.4、

    2024年02月09日
    浏览(40)
  • 在Unity中实现有限状态机

    本文将介绍Unity开发中的有限状态机,给出对应的实现代码。 有限状态机借鉴了图灵机的思想,可以看作是最简单的图灵机。 它包含4要素: 现态 条件 动作 次态 基础的有限状态机不复杂,无非是几个状态定义成类,提供OnEnter/OnExit/OnUpdate方法,这里直接根据需求给出对应的

    2024年02月05日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包