2024-05-05
ReactJS
00
请注意,本文编写于 200 天前,最后修改于 164 天前,其中某些信息可能已经过时。

目录

核心概念
入门案例
接入准备
无装饰器写法
装饰器语法
装饰器语法(跨层级)
store和组件一体式写法
函数组件用法
hook用法
进阶教程
如果想用多个store
inject
runInAction

react和mobx虽然诞生很久很久了,但是网上依旧没有很好的入门学习案例,官方给的一个 十分钟交互式教程 就是扯蛋(后半段内容有跳跃了),网上其他一些文章就是展示,不能直接运行, 我还看了一个Mobx todomvc的案例 竟然是用express + webpack写,给入门开发者的心智负担太重了。

另外跑个demo 不等于会了,mobx可以用普通与语法也可以装饰器语法(虽然我知道用推荐用装饰器语法),但是装饰器分新旧两个版本(虽然我知道使用的是旧的装饰器语法),React 又有class组件和函数组件两种。所以mobx学习如果没有好的教程学起来比较折腾,作为专业的前端,这篇文章带你熟练使用mobx.

核心概念

照例先贴一下官网 Mobx官方文档

官网开头的核心概念多看几遍,,

image.png

  • state
  • computed -- derivations
  • reactions
  • actions

入门案例

接入准备

  • npx create-react-app XXX
  • cd XXX && npm i && npm eject
  • npm i mobx mobx-react
  • 修改package.json babel增加plugins
json
[ "@babel/plugin-proposal-decorators", { "legacy": true } ]

补充还有一种环境搭建方式 使用react-app-rewired

下面以一个最简单的计时器功能为案例, 看一看mobx的玩法

无装饰器写法

js
import {makeObservable, observable, action} from "mobx"; import {observer} from 'mobx-react' class AppState { timer = 0; constructor() { makeObservable(this, { timer: observable, reset: action, add: action }); setInterval(() => { this.add(); }, 1000) } add = () => { this.timer += 1; } reset = () => { this.timer = 0; } } const store = new AppState(); const TimerComp = observer(({store}) => { return <div> <p>{store.timer}</p> <button onClick={store.reset}>reset</button> </div> }) export default function TimerView() { return <div> <TimerComp store={store}></TimerComp> </div> }

装饰器语法

image.png

当然 store也可以改为装饰器语法

image.png

装饰器语法(跨层级)

image.png

store和组件一体式写法

js
import React from 'react'; import {makeObservable, observable, action} from 'mobx'; import { Observer } from 'mobx-react'; class App extends React.Component { constructor(props) { super(props); makeObservable(this); } componentDidMount() { this.timer = setInterval(() => { this.add(); }, 1000) } componentWillUnmount() { clearInterval(this.timer) } @observable count = 0; @action add = () => { ++this.count; } @action reset = () => { this.count = 0; } render() { return <Observer> { () => <div> <p>{this.count}</p> <button onClick={this.reset}>reset</button> </div> } </Observer> } } export default App;

函数组件用法

image.png

hook用法

image.png

本段落完整代码 点这里

进阶教程

如果想用多个store

  • Provider 可以注入多个属性
  • class组件 @inject('store1');@inject('store2')
  • 函数组件 const Comp = inject('store1', 'store2')(ImplComp)

inject

inject的参数可以是一个function 类似JS array.map 或 react-redux的mapState的作用

js
@inject((store) => ({ count: store.counterStore.count, doubleCount: store.counterStore.doubleCount }))

mobx vs redux

十分钟交互式的 MobX + React 教程 可以看,但个人觉得不是很好,尤其后半段内容有跳跃,需要看看其他示例。

@action.bound@action 的区别是, 前者相当于JS的bind绑定this的作用

runInAction

  • 在mobx中要求变更必须使用@action
  • @action中异步的变更推荐用runInAction 包裹

本文作者:郭郭同学

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!