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