javascriptreactjsmobx

mobX: TypeError: Cannot read properties of undefined


I just playground with some code with mobX, and this happened, don't know why but i'm sure it not much different from offical docs

Here is store.tsx

import { observable, computed, action, makeObservable, override, makeAutoObservable } from "mobx"

class CounterStore {
  initValue = 0
  powValue = Math.pow(this.initValue, 2)
  constructor() {
    makeAutoObservable(this)
  }
  increaseNumber() {
    this.initValue = this.initValue + 1
  }
}
const Store = new CounterStore()
export default Store

Here is where i use this. called increasement.tsx

import { observer } from "mobx-react"

export const IncrementButton = observer(({ store }) => {
  return (
    <div>
      <button onClick={store.increaseNumber}>Increase</button>
      <h1>{store.initValue}</h1>
    </div>
  )
})

And index.tsx

ReactDOM.render(
  <React.StrictMode>
    <IncrementButton store={Store} />
    {/* <TestUseState /> */}
    {/* <TestEffect />
     <UseMemoTest /> */}
  </React.StrictMode>,
  document.getElementById("root"),

Weird is, it show initValue, but when i click increase it show can't not read properties Please help, thanks


Solution

  • as @mimoid noticed, your method is not bound to the class and losing context (this). It is not MobX problem, it is just regular javascript feature called late binding.

    Although you don't really need to change makeAutoObservable to makeObservable, you can just use arrow functions, in my opinion it is more "native" way:

    class CounterStore {
      initValue = 0
      powValue = Math.pow(this.initValue, 2)
      constructor() {
        makeAutoObservable(this)
      }
      // Just make it an arrow function
      increaseNumber = () => {
        this.initValue = this.initValue + 1
      }
    }
    

    Alternatively you can pass autoBind option to the makeAutoObservable:

    autoBind: true uses action.bound/flow.bound by default, rather than action/flow. Does not affect explicitly annotated members.

    https://mobx.js.org/observable-state.html#options-