【问题标题】:Mobx makeAutoObservable not binding thisMobx makeAutoObservable 没有绑定这个
【发布时间】: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);

【问题讨论】:

    标签: reactjs observable store mobx mobx-react


    【解决方案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;
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-03-28
        • 1970-01-01
        • 2010-10-22
        • 2019-06-04
        • 1970-01-01
        • 2019-08-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多