我正在使用TypeScript,挂钩和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>
)
}
EDIT:更多信息。我在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
更新时,组件does重新呈现,但是DOM没有更新。控制台会显示'render' true
并按原样显示按钮的表示形式,但是检查文档本身显示那里没有按钮。但是,以某种方式将条件从appStore.ready
更改为appStore.x === 10
does会更新DOM。
事实证明,我在提问中并未提供完整的信息。在创建最小复制品时,我决定尝试从<React.StrictMode>
中删除顶级index.tsx
组件。突然,一切正常。碰巧,[email protected]
是我的项目创建时最新的稳定发行版,在严格模式下效果不佳。在将其添加到稳定版本之前,这两个选项是:
mobx-react-lite@next