Mobx makeAutoObservable 没有绑定这个

Mobx makeAutoObservable not binding this

我已经用一个简单的 MobX 商店构建了一个基本的计数器 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;

使用商店挂钩

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;

React 组件

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);

尽量不要那样破坏商店。 解构时,任何原始变量都将保持最新值,不再可见。 您还需要 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);

它抛出是因为你的方法在调用时丢失了上下文 (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;
  }
}

您还可以在 makeAutoObservable 的选项中使用 autoBind: true:

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

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