【reactjs进阶】react状态管理之mobx6.x的使用的使用(一)

MobX 是一个身经百战的库,它通过运用透明的函数式响应编程使状态管理变得简单和可扩展。他独立于框架存在,不与任何框架耦合,可以搭配任意框架。

环境准备

json 复制代码
	"dependencies": {
		"@testing-library/jest-dom": "^5.17.0",
		"@testing-library/react": "^13.4.0",
		"@testing-library/user-event": "^13.5.0",
		"husky": "^9.1.7",
		"mobx": "^6.13.5",
		"mobx-persist-store": "^1.1.5",
		"mobx-react": "^9.2.0",
		"prettier": "^3.4.2",
		"react": "^18.0.0",
		"react-dom": "^18.0.0",
		"react-scripts": "5.0.1",
		"sass": "^1.83.1",
		"web-vitals": "^2.1.4"
	},
	"scripts": {
		"start": "craco start ",
		"build": "craco build",
		"test": "craco  test",
		"eject": "react-scripts eject",
		"lint": "eslint src  -c eslint.config.mjs --fix",
		"lint:lint-staged": "lint-staged"
	},
	"browserslist": {
		"production": [
			">0.2%",
			"not dead",
			"not op_mini all"
		],
		"development": [
			"last 1 chrome version",
			"last 1 firefox version",
			"last 1 safari version"
		]
	},
	"devDependencies": {
		"@babel/eslint-parser": "^7.26.5",
		"@babel/plugin-proposal-decorators": "^7.25.9",
		"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
		"@commitlint/cli": "^19.6.1",
		"@commitlint/config-conventional": "^19.6.0",
		"@craco/craco": "^7.1.0",
		"@eslint/js": "^9.18.0",
		"eslint": "^8.57.1",
		"eslint-plugin-react": "^7.37.3",
		"globals": "^15.14.0",
		"lint-staged": "^15.3.0",
		"mobx-react-lite": "^4.1.0"
	},

mobx实现的计数器

代码实现

依赖安装

bash 复制代码
npm i mobx mobx-react

数据状态

js 复制代码
import { makeAutoObservable } from 'mobx'
import { observer } from 'mobx-react'

class Timer {
	secondPassed = 0
	constructor() {
		makeAutoObservable(this)
	}
	increase() {
		this.secondPassed++
	}
	reset() {
		this.secondPassed = 0
	}
}
// 单例模式,确保所有组件共享同一个Timer实例
export default new Timer()
  • UI组件
js 复制代码
import { observer } from 'mobx-react'
// 高阶组件
const TimerCount = observer(({ timer }) => {
	return (
		<div>
			<h1>当前时间是:{timer.secondPassed}</h1>
			<button onClick={() => timer.reset()}>重置</button>
		</div>
	)
})

export default TimerCount
  • 组件使用
js 复制代码
import logo from '@/logo.svg'
import { useEffect } from 'react'
import '@/App.css'
import Header from '@/components/header'
import '@/assets/styles/index.scss'
import TimeCount from './components/mobxComp/TimeCount'
import store from './components/mobxComp/store'

function App() {
	useEffect(() => {
		const timer = setInterval(() => {
			store.increase()
		}, 1000)
		return () => {
			clearInterval(timer)
		}
	}, [])
	return (
		<div className='App box'>
			<TimeCount timer={store} />
		</div>
	)
}

export default App

这样就实现了一个使用mobx实现的状态数据管理,很简洁是不是?那是因为mobx底层给我们做了大量的工作。

比如,上面使用到的makeAutoObservable这个api,给我们实现了数据的观测,还有事件的响应,状态的变化的侦测等。

还有一个与makeAutoObservable类似的api,makeObservable,是我们自己去定义响应式数据,和改变状态的方法。

  • 关于makeObservable的使用方法
js 复制代码
import { makeAutoObservable, makeObservable, observable, action } from 'mobx'
import { observer } from 'mobx-react'

class Timer {
	secondPassed = 0
	constructor() {
		makeObservable(this, {
			secondPassed: observable,
			increase: action,
			reset: action,
		})
	}
	increase() {
		this.secondPassed++
	}
	reset() {
		this.secondPassed = 0
	}
}
// 单例模式,确保所有组件共享同一个Timer实例
export default new Timer()

当我们要使用makeObservable的时候,就必须去手动设置一个状态或事件的类型。

  • observable可观测数据
  • computed计算属性
  • action同步事件
  • flow异步事件

这是四个主要的数据和事件的类型,对比其他的状态管理库react-redux,redux-thunk,rtk等等都是类似的

计算数据,类似于vue中的computed,看下实现

js 复制代码
import { makeAutoObservable, makeObservable, observable, action, computed } from 'mobx'
import { observer } from 'mobx-react'

class Timer {
	secondPassed = 0
	constructor() {
		makeObservable(this, {
			secondPassed: observable,
			increase: action,
			reset: action,
			doubleCount: computed,
		})
	}
	increase() {
		this.secondPassed++
	}
	reset() {
		this.secondPassed = 0
	}
	get doubleCount() {
		return this.secondPassed * 2
	}
}
// 单例模式,确保所有组件共享同一个Timer实例
export default new Timer()

项目中获取接口数据的业务,是避免不了的。那怎么实现这种异步事件呢?官网推荐的使用的是gen方式。有点类似dva系列的异步方式,但是比dva的简单直接明了

js 复制代码
import { makeAutoObservable, makeObservable, observable, action, computed, flow } from 'mobx'
import { observer } from 'mobx-react'

class Timer {
	// 数据初始化
	secondPassed = 0
	score = 0
	isFlag = false
	constructor() {
		makeObservable(this, {
			// 数据转化为响应式,框架会自动将数据转化为响应式,并监听变化
			secondPassed: observable,
			increase: action,
			reset: action,
			doubleCount: computed,
			score: observable,
			addScore: action,
			isFlag: observable,
			asyncAddScore: flow,
		})
	}
	increase() {
		this.secondPassed++
	}
	reset() {
		this.secondPassed = 0
	}

	get doubleCount() {
		return this.secondPassed * 2
	}

	addScore(count = 1) {
		this.score += count
	}

	*asyncAddScore() {
		console.log('asyncAddScore')
		this.isFlag = true
		yield new Promise((resolve) =>
			setTimeout(() => {
				this.isFlag = false
				this.addScore(10)
				resolve()
			}, 3000)
		)
	}
}
// 单例模式,确保所有组件共享同一个Timer实例
export default new Timer()

组件使用

js 复制代码
import { observer } from 'mobx-react'

// 高阶组件
const TimerCount = observer(({ timer }) => {
	console.log('🚀 ~ TimerCount ~ timer:', timer)
	return (
		<div>
			<h1>当前时间是:{timer.secondPassed}</h1>
			<p>computed时间:{timer.doubleCount}</p>
			<button onClick={() => timer.reset()}>重置</button>
			<hr />
			<h2>打分:{!timer.isFlag ? timer.score : '正在打分中...'}</h2>
			<p>
				<button onClick={() => timer.addScore(1)}>同步+1分</button>
				<button onClick={() => timer.asyncAddScore()}>异步+10分</button>
			</p>
		</div>
	)
})

export default TimerCount
相关推荐
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端
爱敲代码的小鱼9 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax