mobX: TypeError: Cannot read properties of undefined

Viewed 2729

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

2 Answers

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
  }
}

Change makeAutoObservable to makeObservable and manually assign action.bound to every action instead of action. I had a similar error and it solved it.

Related