Mobx makeAutoObservable 没有绑定这个

Posted

技术标签:

【中文标题】Mobx makeAutoObservable 没有绑定这个【英文标题】:Mobx makeAutoObservable not binding this 【发布时间】:2021-09-21 22:20:26 【问题描述】:

我用一个简单的 MobX 商店构建了一个基本的 Counter React 应用程序。我能够使用 makeObservable 创建一个可观察的 MobX 状态,但由于某种原因,当我尝试使用 makeAutoObservable 时出现错误

Cannot read property 'counter' of undefined

我如何错误地使用makeAutoObservable

商店

import  makeAutoObservable, makeObservable, action, observable  from "mobx";

class SampleStore 
  counter = 0;

  constructor(arg) 
    makeAutoObservable(this);
    // makeObservable(this, 
    //   counter: observable,
    //   increment: action.bound,
    //   decrement: action.bound,
    // );
  

  increment() 
    this.counter++;
    return this.counter;
  

  decrement() 
    this.counter--;
    return this.counter;
  


export default SampleStore;

useStore 钩子

import  createContext, useContext  from "react";

import SampleStore from "./SampleStore";

export const store = 
  sampleStore: new SampleStore(),
;

export const StoreContext = createContext(store);

export const useStore = () => 
  return useContext(StoreContext);
;

提供者

import  store, StoreContext  from "./stores";
import Index from "./layout/Index";

function App() 
  return (
    <StoreContext.Provider value=store>
      <Index />
    </StoreContext.Provider>
  );


export default App;

反应组件

import  useStore  from "../stores";
import  observer  from "mobx-react";

const Index = (props) => 
  const store = useStore();
  const 
    sampleStore:  counter, increment, decrement ,
   = store;
  return (
    <>
      <h1>MobX and React.js example</h1>
      <p>counter</p>
      <button onClick=increment>+</button>
      <button onClick=decrement>-</button>
    </>
  );
;

export default observer(Index);

【问题讨论】:

【参考方案1】:

你也可以在 makeAutoObservable 的选项中使用 autoBind: true:

constructor(arg) 
  makeAutoObservable(this, ,  autoBind: true );

这将自动绑定您的所有操作 - 因此您不会在解构时失去上下文

【讨论】:

【参考方案2】:

尽量不要像那样破坏商店。 解构时,任何原始变量都将保持最新值,不再可观察。 您还需要bind点击方法返回商店。

import  useStore  from "../stores";
import  observer  from "mobx-react";

const Index = (props) => 
  const sampleStore:store = useStore();

  return (
    <>
      <h1>MobX and React.js example</h1>
      <p>store.counter</p>
      <button onClick=store.increment.bind(store)>+</button>
      <button onClick=store.decrement.bind(store)>-</button>
    </>
  );
;

export default observer(Index);

【讨论】:

When destructuring, any primitive variables will remain at the latest values and won't be observable anymore. 这不是真的,在这种情况下,什么时候解构都没关系,因为你的整个组件已经是观察者,任何解构都会被拾取。如果您想分配新值,那将是正确的,但是如果您只需要观察,那也没关系 @Danila 你是对的 store.count 我的错。【参考方案3】:

它抛出是因为你的方法在调用时丢失了上下文 (this)(因为你已经解构了它们)。

它正在使用 makeObservable,因为您使用的是 action.bound,它自动将方法绑定到实例上下文。

如果您想要与 makeAutoObservable 相同的功能,您需要使用箭头函数,如下所示:

class SampleStore 
  counter = 0;

  constructor(arg) 
    makeAutoObservable(this);
  

  // Make it arrow function
  increment = () => 
    this.counter++;
    return this.counter;
  
  
  // Make it arrow function
  decrement = () => 
    this.counter--;
    return this.counter;
  

【讨论】:

以上是关于Mobx makeAutoObservable 没有绑定这个的主要内容,如果未能解决你的问题,请参考以下文章

类组件使用mobx实现数据修改以及请求数据

mobx数据变了,视图没变,mobx6的用法

React--》状态管理工具—Mobx的讲解与使用

[Redux/Mobx] Mobx的设计思想是什么

使用Mobx插件查看mobx的变量值

MobX入门