1.observable

Observable 值可以是JS基本数据类型、引用类型、普通对象、类实例、数组和映射

  1. class Store {
  2. @observable count = 0
  3. //一定要加这一行
  4. constructor(){
  5. makeAutoObservable(this)
  6. }
  7. @action
  8. increment=()=>{
  9. this.count++
  10. }
  11. foo='bar'
  12. }

2.autorun

当你想创建一个响应式函数,而该函数本身永远不会有观察者时,可以使用 mobx.autorun。 这通常是当你需要从反应式代码桥接到命令式代码的情况,例如打印日志、持久化或者更新UI的代码

  1. import {observable,action,makeAutoObservable, autorun} from 'mobx'
  2. autorun(()=>{
  3. //当store.count发生改变。他会自动触发,需要给数据成员加上@observable
  4. console.log(store.count,'gggg');
  5. console.log(store.foo,'gggg');
  6. }

3.computed

计算值(computed values)是可以根据现有的状态或其它计算值衍生出的值。 概念上来说,它们与excel表格中的公式十分相似。 不要低估计算值,因为它们有助于使实际可修改的状态尽可能的小。 此外计算值还是高度优化过的,所以尽可能的多使用它们。

  1. class Store {
  2. @observable price=10
  3. @observable num=5
  4. @computed get totalPice(){
  5. return this.price*this.num
  6. }
  7. }
  1. <p>总价格:{store.totalPice}</p>
  2. <p>总价格:{store.totalPice}</p>
  3. <p>总价格:{store.totalPice}</p>

计算属性存在缓存,使用多次实际只会执行一次,当依赖的属性发生改变他才会重新执行

4.action

4.1 基本使用

需要改变observable中的数据,最好使用action修改,尽可能避免使用store.的方式直接修改

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import {observable,action,makeAutoObservable, autorun,computed} from 'mobx'
  4. import {observer}from 'mobx-react'
  5. //1.初始化mobx仓库
  6. class Store {
  7. @observable count = 0
  8. //一定要加这一行
  9. constructor(){
  10. makeAutoObservable(this)
  11. }
  12. @action
  13. increment=()=>{
  14. this.count++
  15. }
  16. foo='bar'
  17. @observable price=10
  18. @observable num=5
  19. @computed get totalPice(){
  20. return this.price*this.num
  21. }
  22. @action change(){
  23. this.count=10
  24. this.foo='hello'
  25. this.foo='word'
  26. }
  27. }
  28. const store=new Store()
  29. autorun(()=>{
  30. //这里只触发了一次
  31. console.log(store.foo,store.count,'fffrrrf');
  32. })
  33. store.count=20
  34. store.foo='ttt'
  35. store.change()
  36. @observer
  37. class App extends React.Component{
  38. render(){
  39. const {store}=this.props
  40. return(
  41. <div>
  42. <h1>我是一个仓库</h1>
  43. <h2>{store.count}</h2>
  44. <button onClick={store.increment}>增加</button>
  45. <p>总价格:{store.price*store.num}</p>
  46. </div>
  47. )
  48. }
  49. }
  50. ReactDOM.render(
  51. <App store={new Store()}/>,
  52. document.getElementById('root')
  53. );

4.2 action.bound

绑定this,让当前this指向store,注意: action.bound 不要和箭头函数一起使用;箭头函数已经是绑定过的并且不能重新绑定。

4.3 异步action

严格模式下无法直接修改异步方法

  1. import React from "react";
  2. import ReactDOM from "react-dom";
  3. import {
  4. observable,
  5. action,
  6. makeAutoObservable,
  7. autorun,
  8. configure,
  9. runInAction
  10. } from "mobx";
  11. import { observer } from "mobx-react";
  12. configure({
  13. enforceActions: "observed",
  14. });
  15. //初始化mobx仓库
  16. class Store {
  17. @observable count = 0;
  18. @observable num1 = 0;
  19. @observable num2 = 0;
  20. //一定要加这一行
  21. constructor() {
  22. makeAutoObservable(this);
  23. }
  24. @action
  25. increment = () => {
  26. this.count++;
  27. };
  28. //1.定义一个同步函数用于修改,在异步函数中调用
  29. @action.bound
  30. changeCountAsync() {
  31. setTimeout(() => {
  32. this.shngecount()
  33. }, 1000);
  34. }
  35. @action.bound
  36. shngecount(){
  37. this.count=100
  38. }
  39. //2.在异步函数中调用action函数,第一参数是修改函数的名称,这里使用函数自调用
  40. @action.bound
  41. changenum1Async() {
  42. setTimeout(() => {
  43. action('changnum1',()=>{
  44. console.log(this);
  45. this.num1=1002
  46. })()
  47. }, 1000);
  48. }
  49. //3.使用runInAction
  50. @action.bound
  51. changenum2Async() {
  52. setTimeout(() => {
  53. runInAction(()=>{
  54. console.log(this);
  55. this.num2=1003
  56. })
  57. }, 1000);
  58. }
  59. }
  60. const store = new Store();;
  61. autorun(() => {
  62. //当store.count发生改变。他会自动触发,需要给数据成员加上@observable
  63. console.log( store.count, "fffrrrf");
  64. console.log( store.num1, "num1ffrrrf");
  65. console.log( store.num2, "num2ffrrrf");
  66. });
  67. //函数调用
  68. store.changeCountAsync()
  69. store.changenum1Async()
  70. store.changenum2Async()
  71. @observer
  72. class App extends React.Component {
  73. render() {
  74. const { store } = this.props;
  75. return (
  76. <div>
  77. <h1>我是一个仓库</h1>
  78. <h2>{store.count}</h2>
  79. <button onClick={store.increment}>增加</button>
  80. </div>
  81. );
  82. }
  83. }
  84. ReactDOM.render(<App store={new Store()} />, document.getElementById("root"));

5.configure

强制使用action修改数据,使用严格模式。

  1. import {observable,action,makeAutoObservable, autorun,computed,configure} from 'mobx'
  2. configure({
  3. enforceActions:'observed'
  4. })

6.runInAction

  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import {observable,action,makeAutoObservable, autorun,computed,configure,runInAction} from 'mobx'
  4. import {observer}from 'mobx-react'
  5. configure({
  6. enforceActions:'observed'
  7. })
  8. //1.初始化mobx仓库
  9. class Store {
  10. @observable count = 0
  11. @observable foo= 'sxsddde'
  12. //一定要加这一行
  13. constructor(){
  14. makeAutoObservable(this)
  15. }
  16. @action
  17. increment=()=>{
  18. this.count++
  19. }
  20. }
  21. const store=new Store()
  22. autorun(()=>{
  23. console.log(store.foo,store.count,'fffrrrf');
  24. })
  25. //修改数据成员,适用于不定义action
  26. runInAction(()=>{
  27. store.count=10
  28. store.foo='hello'
  29. })
  30. @observer
  31. class App extends React.Component{
  32. render(){
  33. const {store}=this.props
  34. return(
  35. <div>
  36. <h1>我是一个仓库</h1>
  37. <h2>{store.count}</h2>
  38. <button onClick={store.increment}>增加</button>
  39. </div>
  40. )
  41. }
  42. }
  43. ReactDOM.render(
  44. <App store={new Store()}/>,
  45. document.getElementById('root')
  46. );