Реактивное обновление контекста не вызывает повторного рендеринга компонента

Я создаю решение для разделения кода для реагирующего приложения с использованием реагирующего маршрутизатора, веб-пакета и динамического импорта. Идея состоит в том, чтобы отобразить все маршруты и соответствующие компоненты в разные контексты приложения и разделить код в соответствии с контекстами приложения. Когда пользователь посещает какой-либо маршрут, загружается весь фрагмент кода соответствующего контекста приложения.

Примеры кода:

App.tsx:

class App extends React.Component<Props, State> {
  render() {    
    if (this.props.data.loading || this.props.localData.loading) {
      return <Loader />
    }

    return (
      <IntlProvider locale={this.props.localData.session.locale} messages={this.state.translations}>
        <Router history={history}>
            <Route
              exact
              path={`/screens/:action?`}
              render={() => <ComponentLoader contextName={Context.Screens} componentName={'ScreenList'} />}
            />
        </Router>
      </IntlProvider>
    )
  }
}

export default withData(App)

ComponentLoader.tsx:

export enum Context {
  Screens = 'Screens',
  Channels = 'Channels'
}

const CONTEXT_LOADERS: { [name: string]: ComponentChunkLoader } = {
  [Context.Screens]: () => import('../../routerContexts/screens'),
  [Context.Channels]: () => import('../../routerContexts/channels'),
}

const loadedContexts: ContextsCollection = {}

class ComponentLoader extends React.PureComponent<Props, State> {

  state: State = {
    Component: null
  }

  async componentDidMount() {
    this._updateComponent(this.props)
  }

  async componentDidUpdate(prevProps: Props, prevState: State) {
    if (this.props.componentName !== prevProps.componentName || this.props.contextName !== prevProps.contextName) {
      this._updateComponent(this.props)
    }
  }

  _updateComponent = async (props: Props) => {
    let module = loadedContexts[props.contextName]
      ? loadedContexts[props.contextName]
      : await CONTEXT_LOADERS[props.contextName]()

    if (!loadedContexts[props.contextName]) loadedContexts[props.contextName] = module

    let ComponentClass = module[props.componentName]

    this.setState({
      Component: ComponentClass
    })
  }

  render() {

    if (this.state.Component !== null) {
      return <this.state.Component />
    }

    return <Loader />
  }
}

export default ComponentLoader

Поэтому, когда я переключаюсь на разные маршруты, я вижу все компоненты правильно, и разделение кода работает правильно.

Проблема в том, что когда данные в контексте реагируют на обновления, ScreenList Компонент в примере не обновляется. Когда я прохожу ScreenList напрямую реагировать роутер Route все работает хорошо. Так что проблема в моем ComponentLoader компонент, который я использую для разделения кода.

Есть идеи, в чем может быть причина?

ОБНОВЛЕНИЕ: Alrite, что я понял сейчас: если я заверну ComponentLoader в HOC, который вводит некоторые данные из контекста (например, export default withRouter(ComponentLoader)), все работает хорошо и компоненты перерисовываются, как и ожидалось. Почему так происходит?

0 ответов

Другие вопросы по тегам