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



我正在使用TypeScript、hook和mobx-react-lite开始一个新的create-react-app应用程序。尽管过去曾在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>
)
}

编辑:更多信息。我在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。

事实证明,我在问题中没有给出完整的信息。在创建最小复制时,我决定尝试从index.tsx中删除顶级<React.StrictMode>组件。突然间,一切都好了。碰巧的是,mobx-react-lite@1.5.2,在我的项目创建时最新的稳定版本,在严格模式下表现不佳。在添加到稳定版本之前,有两种选择:

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

最新更新