最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - mobX: TypeError: Cannot read properties of undefined - Stack Overflow

programmeradmin13浏览0评论

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

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

Share Improve this question asked Sep 7, 2021 at 23:50 Lê Quốc KhánhLê Quốc Khánh 6051 gold badge9 silver badges25 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 16

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-

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

发布评论

评论列表(0)

  1. 暂无评论