【问题标题】:MobX observable boolean does not re-render component, but observable number doesMobX observable boolean 不会重新渲染组件,但 observable number 会
【发布时间】:2020-04-03 23:37:59
【问题描述】:

我正在使用 TypeScript、钩子和 mobx-react-lite 开始使用新的 create-react-app 应用程序。尽管过去在 React Native 应用程序中广泛使用过 MobX,但我遇到了一个对我来说没有任何意义的问题。

我有一个商店,里面有两个 observable:一个数字和一个布尔值。有一个 initialize() 方法运行一些库代码,在成功回调中,它将数字和布尔值设置为不同的值(见下面的 A 行和 B 行)。

问题:我的组件仅在存在 A 行时重新呈现自身。在这种情况下,初始化完成后,会出现“就绪”文本,并出现按钮。如果我删除 B 行,“就绪”文本仍然会出现。但是如果我删除 A 行(并保留 B 行),按钮永远不会呈现。我检查了一百多次,一切都正确导入,我打开了装饰器支持。我无法想象为什么观察一个数字可以触发重新渲染,但观察一个布尔值却不能。恐怕我在这里遗漏了一些非常明显的东西。有什么想法吗?

相关的简化代码如下:

// store/app.store.ts
export class AppStore {
  @observable ready = false
  @observable x = 5

  initialize() {
    // Takes a callback
    ThirdPartyService.init(() => {
      this.ready = true
      this.x = 10
    })
  }
}
// context/stores.ts

const appStore = new AppStore()
const storesContext = React.createContext({
  appStore
})

export const useStores = () => React.useContext(storesContext)
// App.tsx
const App = observer(() => {
  const { appStore } = useStores()

  useEffect(() => {
    appStore.initialize()
  }, [appStore])

  return (
    <div>
      { appStore.x === 10 && 'ready' } // <-- Line A
      { appStore.ready && <button>Go</button> } // <-- Line B
    </div>
  )
}

编辑:更多信息。我在App 组件的return 语句之前添加了一些日志记录语句。我还将button 条件重构为const。这可能会提供更多见解:

const button = appStore.ready ? <button>Go</button> : null
console.log('render', appStore.ready)
console.log('button', button)

return (
  <div className="App">
    <header className="App-header">{button}</header>
  </div>
)

appStore.ready 更新时,组件重新渲染,但 DOM 不会更新。控制台显示'render' true 并按原样显示按钮的表示,但检查文档本身显示没有按钮。不过,不知何故,将条件从 appStore.ready 更改为 appStore.x === 10 确实会更新 DOM。

【问题讨论】:

  • 代码看起来确实很正常。你能创建一个最小的复制品(例如作为 github 上的独立项目)吗?
  • 实际上...我在 initialize() 上没有看到 @action 装饰器 - 它只是从示例代码中省略了,还是在实际应用程序中实际上丢失了?
  • @amakhrov 它在应用程序中丢失,但我尝试用@action@action.bound 装饰initialize(),并尝试在readyx 内运行更新runInAction(),但不幸的是没有一个有所作为。我会尽快复制并在此处链接,谢谢。与此同时,我还更新了我的问题,提供了更多信息。

标签: javascript reactjs typescript mobx


【解决方案1】:

原来我在我的问题中没有提供完整的信息。在创建最小复制时,我决定尝试从index.tsx 中删除顶级&lt;React.StrictMode&gt; 组件。突然间,一切都奏效了。碰巧的是,mobx-react-lite@1.5.2,在我的项目创建时最新的稳定版本,在严格模式下不能很好地发挥作用。在将其添加到稳定版本之前,这两个选项是:

  • 从 React 组件树中移除严格模式
  • 使用mobx-react-lite@next

【讨论】:

    猜你喜欢
    • 2017-06-09
    • 2020-09-15
    • 1970-01-01
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多