MobX: Ошибка типа: Не удается прочитать свойства неопределенного

#javascript #reactjs #mobx

Вопрос:

Я просто играл с каким-то кодом с MobX, и это произошло, не знаю почему, но я уверен, что это не сильно отличается от официальных документов

Вот магазин.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
 

Вот где я это использую. называется 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>
  )
})
 

И индекс.tsx

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

Странно, это видно initValue , но когда я нажимаю увеличить, это видно can't not read properties
Пожалуйста, помогите, спасибо

Ответ №1:

как заметил @mimoid, ваш метод не привязан к классу и теряет контекст ( this ). Это не проблема MobX, это просто обычная функция javascript, называемая поздней привязкой.

Хотя на самом деле вам не нужно менять makeAutoObservable makeObservable , вы можете просто использовать функции со стрелками, на мой взгляд, это более «родной» способ:

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

Ответ №2:

Измените makeAutoObservable значение makeObservable и назначьте action.bound каждое действие вручную вместо action . У меня была похожая ошибка, и она ее разрешила.

Комментарии:

1. Спасибо за ваш ответ