mobx在react中的使用步骤

安装依赖包

npm i mobx-react@6.1.3 mobx@5.13.0
# or
yarn add mobx-react@6.1.3 mobx@5.13.0

核心api

定义可观察数据

假设声明可观察数据的文件名为test.js

方式一

使用observable()函数

import { observable } from 'mobx';

export default observable({
    name: 'xxxx',
    age: 20
})

方式二

使用在class上使用装饰器

class Test {
    @observable name = '123'
    @observable age = 20
}

export default new Test();

声明要监测数据的视图

在视图中使用的可观察数据发生变化后,mobx会使当前使用可观察数据的组件重新渲染

类组件

使用@observer装饰器.如果TestComponent组件中使用的可观察数据发生变化,该组件会被重新渲染。
只能监测当前组件,不能深入子组件。想要深入子组件,需要子组件使用@observer

import { observer } from 'mobx-react'
import MobxData from './test.js'
@observer
class TestComponent extends React.Component {
    render() {
        // use observable data
        return <div>{MobxData.name}</div>
    }
}

函数式组件

使用useObserver()或者observer()只能监测当前包裹的内容,不能深入子组件。想要深入子组件,需要子组件使用useObserver()observer()

import { useObserver } from 'mobx-react';
import MobxData from './test.js'
const TestComponent = observer(() => {
    // use observable data
    return <div>{MobxData.name}</div>
});

// function TestComponent() {
//    // use observable data
//    return useObserver(() => <div>{MobxData.name}</div>);
// });

代码实现

使用函数式组件演示

定义共享数据

import { action, observable } from "mobx";

// 使用装饰器
// class MobxData {
//   @observable name = 'zoe';
//   @observable age = 12

//   @action.bound
//   setName(name: string) {
//     this.name = name
//   }

// }

// export default new MobxData()

export default observable({
  name: 'xxx',
  age: 18
})

创建组件

import React from 'react'
import {useObserver} from 'mobx-react'
import commonData from './MobxData'

function Child () {
  const onClick = () => {
    commonData.name = Math.random() * 100 + '_zhangsan'
  }
  console.log('child render')
  return useObserver(() => (
    <div>
        Welcome {commonData.name}!You're 12 years old.
        <button onClick={onClick}>change name</button>
    </div>
  ))
}
function Child2 () {
  const onClick = () => {
    commonData.age = Math.random() * 100
  }
  console.log('child2 render')
  return useObserver(() => (
    <div>
        Welcome xxx!You're {commonData.age} years old.
        <button onClick={onClick}>change age</button>
    </div>
  ))
}

// const Child2 = observer(() => {
//   const onClick = () => {
//     commonData.age = Math.random() * 100
//   }
//   console.log('child2 render')
//   return (
//     <div>
//         Welcome xxx!You're {commonData.age} years old.
//         <button onClick={onClick}>change age</button>
//     </div>
//   )
// })

function Parent() {
  return useObserver(() => (<>
    <Child/>
    <Child2/>
    <button onClick={() => {
      commonData.name = Math.random() * 100 + '_qweqweqwe'
    }}>修改名字</button>
    </>))
}

// const Parent = observer(() => (
//   <>
//     <Child/>
//     <Child2/>
//     <button onClick={() => {
//       commonData.name = Math.random() * 100 + '_qweqweqwe'
//     }}>修改名字</button>
//   </>
// ))

// @observer
// class Parent extends React.Component{
//   render() {
//     return (
//       <>
//         <Child/>
//         <Child2/>
//         <button onClick={() => {
//           commonData.name = Math.random() * 100 + '_qweqweqwe'
//         }}>修改名字</button>
//       </>
//     )
//   }
// }

export default function App() {
  return (
    <div>App
      <Parent/>
    </div>
  )
}

主文件

import ReactDOM from 'react-dom'
import Parent from './Parent'


ReactDOM.render(<Parent />, document.querySelector('#root'))

总结

  • 起一个文件,使用mobxobservable()或者@observable创建共享数据并导出
  • 在视图中使用mobx-reactuseObserver()或者observer()或者@observer监测组件中可观察数据的变化
    • 在某组件使用的可观察数据发生变化时该组件会被rerender

填脑坑

@action@action.bound有什么区别?

示例代码

import { action } from "mobx";
class Store {
  unbound() {
    console.log('unbound', this)
  }
  arrow = () => {
    console.log('arrow', this)
  }
  @action unboundAction() {
    console.log('unboundAction', this)
  }
  @action.bound unboundActionBound() {
    console.log('unboundActionBound', this)
  }
  @action arrowAction = () => {
    console.log('arrowAction', this)
  }      
  @action.bound arrowActionBound = () => {
    console.log('arrowActionBound', this)
  }
}

const store = new Store();
const unbound = store.unbound;
const arrow = store.arrow;
const unboundAction = store.unboundAction;
const arrowAction = store.arrowAction;
const unboundActionBound = store.unboundActionBound;
const arrowActionBound = store.arrowActionBound;
console.log(store)
unbound();
arrow();
unboundAction();
arrowAction();
unboundActionBound();
arrowActionBound();

运行后,可以看到日志输出如下

image.png

对原型的影响:

image.png

对this的影响

image.png

但是mobx不推荐action.bound和箭头函数一起使用

注意: action.bound 不要和箭头函数一起使用;箭头函数已经是绑定过的并且不能重新绑定。

useObserver()observer()的区别?

  • useObserver()在函数内使用。监测函数的返回值,使用方式像useMemo
  • observer()在函数外使用。监测高阶组件,使用方式像React.memo

以函数式组件为例

const Parent = observer(() => (
  <>
    <Child/>
    <Child2/>
    <button onClick={() => {
      commonData.name = Math.random() * 100 + '_qweqweqwe'
    }}>修改名字</button>
  </>
))

function Parent() {
  return useObserver(() => (
    <>
      <Child/>
      <Child2/>
      <button onClick={() => {
        commonData.name = Math.random() * 100 + '_qweqweqwe'
      }}>修改名字</button>
    </>
  ))
}

参考链接

action (动作)

React 状态管理工具 Mobx 基本使用_。烦啦的博客-程序员秘密

https://stackoverflow.com/questions/48639891/difference-between-mobxs-action-bound-and-arrow-functions-on-class-functions

原文地址:http://www.cnblogs.com/zoexu/p/16794762.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性