Наблюдаемый логический MobX не переопределяет компонент, но наблюдаемое число делает - PullRequest
0 голосов
/ 03 апреля 2020

Я начинаю работу с новым 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.

1 Ответ

0 голосов
/ 03 апреля 2020

Оказывается, я не совсем дал полную информацию в своем вопросе. Пока я создавал минимальное воспроизведение, я решил попробовать удалить компонент <React.StrictMode> верхнего уровня из index.tsx. Внезапно все заработало. Как оказалось, mobx-react-lite@1.5.2, самая последняя стабильная версия на момент создания моего проекта, не очень хорошо работает в строгом режиме. Пока он не добавлен в стабильный выпуск, доступны два параметра:

  • Удалить строгий режим из дерева компонентов React
  • Использовать mobx-react-lite@next
...