MobX可观察的布尔值不会重新渲染组件,但是可观察的数字却可以

时间:2020-04-03 04:03:01

标签: javascript reactjs typescript mobx

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

我有一家商店有两个可观察值:一个数字和一个布尔值。有一个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>
  )
}

编辑:更多信息。我在return组件的App语句之前添加了一些日志记录语句。我也将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。

1 个答案:

答案 0 :(得分:1)

结果是,我在问题中并未提供完整的信息。在创建最小复制品时,我决定尝试从<React.StrictMode>中删除顶级index.tsx组件。突然,一切正常。碰巧,mobx-react-lite@1.5.2是我的项目创建时最新的稳定版本,在严格模式下效果不佳。在将其添加到稳定版本之前,这两个选项是:

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