首页 > 其他分享 >mobx在react中的使用

mobx在react中的使用

时间:2022-10-15 18:44:44浏览次数:92  
标签:observable const name observer react mobx 使用 组件

mobx在react中的使用步骤

安装依赖包

npm i [email protected] [email protected]
# or
yarn add [email protected] [email protected]

核心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

标签:observable,const,name,observer,react,mobx,使用,组件
From: https://www.cnblogs.com/zoexu/p/16794762.html

相关文章

  • 【C++】统计string里面出现的字符的个数(使用count函数)
    题目:给出一个string字符串,统计里面出现的字符的个数解决方案:使用算法库<algorithm>里面的count函数(不是s.count()!!count是单独作为一个函数,而不是作为一个方法),使用方法是......
  • AcWing 算法提高课 通过递推求等比数列的和(防止使用逆元出现问题)
    基于分治的思想:  例题:https://www.acwing.com/problem/content/99/模板:求num^0+num^1+...+num^kconstintMOD=9901;intQuickExp(intbase,intexp){bas......
  • WinForm中Scale使用初步理解
      ClientSize=newSize(102,126);此客户区域的尺寸与上面的newCalcButton(this,"+",'+',62,24,14,14)等各构造函数的定位尺寸是一套体系;而Scale(Font.Height/9f);是......
  • openpyxl模块的基础使用
    1.安装pipinstallopenpyxl2.打开文件①创建fromopenpyxlimportWorkbook#实例化wb=Workbook()#激活worksheetws=wb.active②打开已有fromo......
  • 使用python爬虫爬取数据集保存到csv或者excel中
    准备下载库在编写代码时需要使用的python库要提前下载pipinstallbeautifulsoup4pipinstallopenpyxlpipinstallrequests相关库的文档openpyxl-读/写Excel......
  • Stream流的使用
    Stream流的使用获取stream流的两个方法所有的Collection集合都可以通过stream默认方法获取流。defaultStream<E>()Stream接口的静态方法of可以获取数组对......
  • postgresql使用备忘
    打开postgresqlsudo-upostgrespsql语句执行时间EXPLAINANALYZEExecutionTime:SQL语句的执行时间Planningtime则是SQL语句生成查询计划所花费的时间参考:(31......
  • Go入坑 bufio使用
    bufio包实现了有缓冲的I/O,它封装了一个io.Reader或io.Write接口对象,创建一个实现实现了该接口,同时提供缓冲和一些文本I/O的帮助函数. 简单的说就是,把文件读取进缓冲(内......
  • k8s将dockershim移除之后,如何继续使用docker?
     从哪里移除 说说这个前提,就是k8s宣布将dockershim给移除了这么个点 为什么要移除说白了,就是k8s是想建立标准的,通过的CRI,容器运行的接口,不仅仅可以支持d......
  • springboot导出数据到Excel表格,使用EasyExcel
    1.导入依赖导出方法需要使用到fastJson的依赖,这里也直接导入点击查看代码<!--阿里的easyexcel--><dependency><groupId>com.alibaba</groupId>......