Я начинаю работу с новым create-react-app
приложением, использующим TypeScript, ловушки и mobx-react-lite
. Несмотря на то, что в прошлом я активно использовал MobX в приложении React Native, я столкнулся с проблемой, которая не имеет для меня никакого смысла.
У меня есть магазин с двумя наблюдаемыми: одно число и одно логическое значение , Существует метод 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.