Реактивное обновление контекста не вызывает повторного рендеринга компонента
Я создаю решение для разделения кода для реагирующего приложения с использованием реагирующего маршрутизатора, веб-пакета и динамического импорта. Идея состоит в том, чтобы отобразить все маршруты и соответствующие компоненты в разные контексты приложения и разделить код в соответствии с контекстами приложения. Когда пользователь посещает какой-либо маршрут, загружается весь фрагмент кода соответствующего контекста приложения.
Примеры кода:
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)
), все работает хорошо и компоненты перерисовываются, как и ожидалось. Почему так происходит?